mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-30 18:23:35 +08:00
feat(region,host-deployer): ipv6 only guest support (#22896)
This commit is contained in:
@@ -101,7 +101,7 @@ require (
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
|
||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
|
||||
yunion.io/x/pkg v1.10.4-0.20250712095850-7797c1f3ffa6
|
||||
yunion.io/x/pkg v1.10.4-0.20250715023532-99a31ea00303
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250531010554-ce98f840b833
|
||||
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c
|
||||
|
||||
@@ -1423,8 +1423,8 @@ yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 h1:Hu/4ERvoWaN6aiFs4h4/yvVB
|
||||
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
|
||||
yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v1.10.4-0.20250712095850-7797c1f3ffa6 h1:CzEjNUur33HGmDkW7uKw1eU97gwojNsXlB2AMEzItn8=
|
||||
yunion.io/x/pkg v1.10.4-0.20250712095850-7797c1f3ffa6/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
|
||||
yunion.io/x/pkg v1.10.4-0.20250715023532-99a31ea00303 h1:gbAWm7tVNr0mZjLMJa1A6P85tHsuEpDEEnUHz0+mBhw=
|
||||
yunion.io/x/pkg v1.10.4-0.20250715023532-99a31ea00303/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4=
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250531010554-ce98f840b833 h1:XTFC1naKYkciCQDLm9izpzHXfTenmmtYsTpVKrsN5hE=
|
||||
|
||||
@@ -90,6 +90,10 @@ type NetworkConfig struct {
|
||||
// required: false
|
||||
RequireIPv6 bool `json:"require_ipv6"`
|
||||
|
||||
// 只分配IPv6地址,禁用IPv4
|
||||
// required: false
|
||||
StrictIPv6 bool `json:"strict_ipv6"`
|
||||
|
||||
// 驱动方式
|
||||
// 若指定镜像的网络驱动方式,此参数会被覆盖
|
||||
Driver string `json:"driver"`
|
||||
|
||||
@@ -336,6 +336,9 @@ func ParseNetworkConfig(desc string, idx int) (*compute.NetworkConfig, error) {
|
||||
netConfig.IsDefault = true
|
||||
} else if p == "ipv6" {
|
||||
netConfig.RequireIPv6 = true
|
||||
} else if p == "strict-ipv6" {
|
||||
netConfig.RequireIPv6 = true
|
||||
netConfig.StrictIPv6 = true
|
||||
} else if strings.HasPrefix(p, "standby-port=") {
|
||||
netConfig.StandbyPortCount, _ = strconv.Atoi(p[len("standby-port="):])
|
||||
} else if strings.HasPrefix(p, "standby-addr=") {
|
||||
|
||||
@@ -2630,6 +2630,10 @@ func (self *SGuest) PerformChangeIpaddr(
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("parseNetworkInfo fail: %s", err)
|
||||
}
|
||||
if len(gn.IpAddr) == 0 && len(conf.Address) > 0 {
|
||||
// strict ipv6 network, can't add ipv4 address
|
||||
return nil, httperrors.NewBadRequestError("guest network has no ipv4 address")
|
||||
}
|
||||
reuseV4 := ""
|
||||
if conf.Address == gn.IpAddr {
|
||||
// 允许IPv4地址不变,只改IPv6地址
|
||||
|
||||
@@ -253,6 +253,7 @@ type newGuestNetworkArgs struct {
|
||||
|
||||
ip6Addr string
|
||||
requireIPv6 bool
|
||||
strictIPv6 bool
|
||||
|
||||
// 是否为缺省路由
|
||||
isDefault bool
|
||||
@@ -298,6 +299,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
|
||||
address6 = args.ip6Addr
|
||||
requireIPv6 = args.requireIPv6
|
||||
strictIPv6 = args.strictIPv6
|
||||
)
|
||||
|
||||
gn.GuestId = guest.Id
|
||||
@@ -325,7 +327,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
}
|
||||
|
||||
provider := vpc.GetProviderName()
|
||||
if !virtual {
|
||||
if !virtual && !strictIPv6 && network.IsSupportIPv4() {
|
||||
if len(address) > 0 && reUseAddr {
|
||||
ipAddr, err := netutils.NewIPV4Addr(address)
|
||||
if err != nil {
|
||||
@@ -386,7 +388,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
|
||||
// assign ipv6 address
|
||||
if !virtual {
|
||||
if len(address6) > 0 || requireIPv6 {
|
||||
if len(address6) > 0 || (requireIPv6 || len(gn.IpAddr) == 0) {
|
||||
if provider == api.CLOUD_PROVIDER_ONECLOUD || options.Options.EnablePreAllocateIpAddr || (!options.Options.EnablePreAllocateIpAddr && len(address6) > 0) {
|
||||
addrTable := network.GetUsedAddresses6(ctx)
|
||||
recentAddrTable := manager.getRecentlyReleasedIPAddresses6(network.Id, network.getAllocTimoutDuration())
|
||||
@@ -1081,7 +1083,7 @@ func (gn *SGuestnetwork) getMtu(net *SNetwork) int16 {
|
||||
func (gn *SGuestnetwork) IsAllocated() bool {
|
||||
region, _ := gn.GetGuest().getRegion()
|
||||
provider := region.Provider
|
||||
if regutils.MatchMacAddr(gn.MacAddr) && (gn.Virtual || regutils.MatchIP4Addr(gn.IpAddr) || (provider != api.CLOUD_PROVIDER_ONECLOUD && !options.Options.EnablePreAllocateIpAddr)) {
|
||||
if regutils.MatchMacAddr(gn.MacAddr) && (gn.Virtual || regutils.MatchIP4Addr(gn.IpAddr) || regutils.MatchIP6Addr(gn.Ip6Addr) || (provider != api.CLOUD_PROVIDER_ONECLOUD && !options.Options.EnablePreAllocateIpAddr)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -3506,6 +3506,7 @@ type Attach2NetworkArgs struct {
|
||||
RequireDesignatedIP bool
|
||||
UseDesignatedIP bool
|
||||
RequireIPv6 bool
|
||||
StrictIPv6 bool
|
||||
|
||||
BwLimit int
|
||||
NicDriver string
|
||||
@@ -3536,6 +3537,7 @@ func (args *Attach2NetworkArgs) onceArgs(i int) attach2NetworkOnceArgs {
|
||||
requireDesignatedIP: args.RequireDesignatedIP,
|
||||
useDesignatedIP: args.UseDesignatedIP,
|
||||
requireIPv6: args.RequireIPv6,
|
||||
strictIPv6: args.StrictIPv6,
|
||||
|
||||
bwLimit: args.BwLimit,
|
||||
nicDriver: args.NicDriver,
|
||||
@@ -3578,6 +3580,7 @@ type attach2NetworkOnceArgs struct {
|
||||
requireDesignatedIP bool
|
||||
useDesignatedIP bool
|
||||
requireIPv6 bool
|
||||
strictIPv6 bool
|
||||
|
||||
bwLimit int
|
||||
nicDriver string
|
||||
@@ -3656,6 +3659,7 @@ func (self *SGuest) attach2NetworkOnce(
|
||||
requireDesignatedIP: args.requireDesignatedIP,
|
||||
useDesignatedIP: args.useDesignatedIP,
|
||||
requireIPv6: args.requireIPv6,
|
||||
strictIPv6: args.strictIPv6,
|
||||
|
||||
ifname: args.nicConf.Ifname,
|
||||
macAddr: args.nicConf.Mac,
|
||||
@@ -4429,6 +4433,7 @@ func (self *SGuest) attach2NamedNetworkDesc(ctx context.Context, userCred mcclie
|
||||
IpAddr: netConfig.Address,
|
||||
Ip6Addr: netConfig.Address6,
|
||||
RequireIPv6: netConfig.RequireIPv6,
|
||||
StrictIPv6: netConfig.StrictIPv6,
|
||||
NicDriver: netConfig.Driver,
|
||||
NumQueues: netConfig.NumQueues,
|
||||
BwLimit: netConfig.BwLimit,
|
||||
@@ -6576,6 +6581,9 @@ func (self *SGuest) ToNetworksConfig() []*api.NetworkConfig {
|
||||
netConf.Exit = guestNetwork.IsExit()
|
||||
if len(guestNetwork.Ip6Addr) > 0 {
|
||||
netConf.RequireIPv6 = true
|
||||
if len(guestNetwork.IpAddr) == 0 {
|
||||
netConf.StrictIPv6 = true
|
||||
}
|
||||
}
|
||||
// netConf.Private
|
||||
// netConf.Reserved
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -94,11 +96,11 @@ type SNetwork struct {
|
||||
IfnameHint string `width:"9" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
|
||||
// 起始IP地址
|
||||
GuestIpStart string `width:"16" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"`
|
||||
GuestIpStart string `width:"16" charset:"ascii" nullable:"false" list:"user" update:"user" create:"optional"`
|
||||
// 结束IP地址
|
||||
GuestIpEnd string `width:"16" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"`
|
||||
GuestIpEnd string `width:"16" charset:"ascii" nullable:"false" list:"user" update:"user" create:"optional"`
|
||||
// 掩码
|
||||
GuestIpMask int8 `nullable:"false" list:"user" update:"user" create:"required"`
|
||||
GuestIpMask int8 `nullable:"false" list:"user" update:"user" create:"optional"`
|
||||
// 网关地址
|
||||
GuestGateway string `width:"16" charset:"ascii" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
// DNS, allow multiple dns, seperated by ","
|
||||
@@ -618,6 +620,9 @@ func (snet *SNetwork) GetGuestIpv4StartAddress() netutils.IPV4Addr {
|
||||
}
|
||||
|
||||
func (snet *SNetwork) IsExitNetwork() bool {
|
||||
if len(snet.GuestIpStart) == 0 {
|
||||
return false
|
||||
}
|
||||
return len(snet.ExternalId) == 0 && netutils.IsExitAddress(snet.GetGuestIpv4StartAddress())
|
||||
}
|
||||
|
||||
@@ -861,7 +866,11 @@ func (manager *SNetworkManager) newFromCloudNetwork(ctx context.Context, userCre
|
||||
}
|
||||
|
||||
func (net *SNetwork) IsAddressInRange(address netutils.IPV4Addr) bool {
|
||||
return net.getIPRange().Contains(address)
|
||||
ipRange := net.getIPRange()
|
||||
if ipRange == nil {
|
||||
return false
|
||||
}
|
||||
return ipRange.Contains(address)
|
||||
}
|
||||
|
||||
func (net *SNetwork) IsAddress6InRange(address netutils.IPV6Addr) bool {
|
||||
@@ -1012,7 +1021,7 @@ func (manager *SNetworkManager) TotalPortCount(
|
||||
stat, _ = ret[net.ServerType]
|
||||
}
|
||||
allStat, _ = ret[""]
|
||||
count := net.getIPRange().AddressCount()
|
||||
count := net.GetTotalAddressCount()
|
||||
if net.IsExitNetwork() {
|
||||
if len(net.ServerType) > 0 {
|
||||
stat.CountExt += count
|
||||
@@ -1070,7 +1079,19 @@ func (snet *SNetwork) GetFreeAddressCount() (int, error) {
|
||||
}
|
||||
|
||||
func (snet *SNetwork) GetTotalAddressCount() int {
|
||||
return snet.getIPRange().AddressCount()
|
||||
ipRange := snet.getIPRange()
|
||||
if ipRange != nil {
|
||||
return ipRange.AddressCount()
|
||||
}
|
||||
ip6Range := snet.getIPRange6()
|
||||
if ip6Range == nil {
|
||||
return 0
|
||||
}
|
||||
cnt := ip6Range.AddressCount()
|
||||
if cnt.Cmp(big.NewInt(math.MaxInt32)) > 0 {
|
||||
return math.MaxInt32
|
||||
}
|
||||
return int(cnt.Int64())
|
||||
}
|
||||
|
||||
func (snet *SNetwork) getFreeAddressCount() (int, error) {
|
||||
@@ -1082,19 +1103,7 @@ func (snet *SNetwork) getFreeAddressCount() (int, error) {
|
||||
if nics, ok := vnics[snet.Id]; ok {
|
||||
used = nics.Total
|
||||
}
|
||||
return snet.getIPRange().AddressCount() - used, nil
|
||||
}
|
||||
|
||||
func (snet *SNetwork) getFreeAddress6Count() (int, error) {
|
||||
vnics, err := NetworkManager.TotalNicCount([]string{snet.Id})
|
||||
if err != nil {
|
||||
return -1, errors.Wrapf(err, "TotalNicCount")
|
||||
}
|
||||
used := 0
|
||||
if nics, ok := vnics[snet.Id]; ok {
|
||||
used = nics.Total
|
||||
}
|
||||
return snet.getIPRange().AddressCount() - used, nil
|
||||
return snet.GetTotalAddressCount() - used, nil
|
||||
}
|
||||
|
||||
func isValidNetworkInfo(ctx context.Context, userCred mcclient.TokenCredential, netConfig *api.NetworkConfig, reuseAddr string) error {
|
||||
@@ -1280,10 +1289,6 @@ func IsExitNetworkInfo(ctx context.Context, userCred mcclient.TokenCredential, n
|
||||
return false
|
||||
}
|
||||
|
||||
func (snet *SNetwork) GetPorts() int {
|
||||
return snet.getIPRange().AddressCount()
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) FetchCustomizeColumns(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
@@ -1311,7 +1316,7 @@ func (manager *SNetworkManager) FetchCustomizeColumns(
|
||||
if network.IsClassic() {
|
||||
rows[i].IsClassic = true
|
||||
}
|
||||
rows[i].Ports = network.GetPorts()
|
||||
rows[i].Ports = network.GetTotalAddressCount()
|
||||
rows[i].Routes = network.GetRoutes()
|
||||
rows[i].Schedtags = GetSchedtagsDetailsToResourceV2(network, ctx)
|
||||
rows[i].Dns = network.GetDNS(rows[i].Zone)
|
||||
@@ -1874,7 +1879,7 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
}
|
||||
|
||||
var (
|
||||
ipRange netutils.IPV4AddrRange
|
||||
ipRange *netutils.IPV4AddrRange
|
||||
masklen int8
|
||||
netAddr netutils.IPV4Addr
|
||||
)
|
||||
@@ -1883,7 +1888,8 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
if err != nil {
|
||||
return input, httperrors.NewInputParameterError("ip_prefix error: %s", err)
|
||||
}
|
||||
ipRange = prefix.ToIPRange()
|
||||
ipRangeTmp := prefix.ToIPRange()
|
||||
ipRange = &ipRangeTmp
|
||||
masklen = prefix.MaskLen
|
||||
netAddr = prefix.Address.NetAddr(masklen)
|
||||
input.GuestIpMask = prefix.MaskLen
|
||||
@@ -1928,7 +1934,8 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
if err != nil {
|
||||
return input, httperrors.NewInputParameterError("invalid end ip: %s %s", input.GuestIpEnd, err)
|
||||
}
|
||||
ipRange = netutils.NewIPV4AddrRange(ipStart, ipEnd)
|
||||
ipRangeTpm := netutils.NewIPV4AddrRange(ipStart, ipEnd)
|
||||
ipRange = &ipRangeTpm
|
||||
masklen = input.GuestIpMask
|
||||
netAddr = ipStart.NetAddr(masklen)
|
||||
if ipEnd.NetAddr(masklen) != netAddr {
|
||||
@@ -1995,6 +2002,10 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
}
|
||||
}
|
||||
|
||||
if ipRange == nil && ipRange6 == nil {
|
||||
return input, httperrors.NewBadRequestError("No valid ipv4/ipv6 address input")
|
||||
}
|
||||
|
||||
// do not set default dns
|
||||
// if len(input.GuestDns) == 0 {
|
||||
// input.GuestDns = options.Options.DNSServer
|
||||
@@ -2048,9 +2059,10 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
}
|
||||
|
||||
{
|
||||
if !vpc.containsIPV4Range(ipRange) {
|
||||
if ipRange != nil && !vpc.containsIPV4Range(*ipRange) {
|
||||
return input, httperrors.NewInputParameterError("Network not in range of VPC cidrblock %s", vpc.CidrBlock)
|
||||
}
|
||||
|
||||
if ipRange6 != nil {
|
||||
if !vpc.containsIPV6Range(*ipRange6) {
|
||||
return input, httperrors.NewInputParameterError("Network not in range of VPC ipv6 cidrblock %s", vpc.CidrBlock6)
|
||||
@@ -2064,7 +2076,7 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
if err != nil {
|
||||
return input, httperrors.NewInternalServerError("fail to GetNetworks of vpc: %v", err)
|
||||
}
|
||||
if isOverlapNetworks(nets, ipRange) {
|
||||
if ipRange != nil && isOverlapNetworks(nets, *ipRange) {
|
||||
return input, httperrors.NewInputParameterError("Conflict address space with existing networks in vpc %q", vpc.GetName())
|
||||
}
|
||||
if ipRange6 != nil && isOverlapNetworks6(nets, *ipRange6) {
|
||||
@@ -2072,8 +2084,10 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
}
|
||||
}
|
||||
|
||||
input.GuestIpStart = ipRange.StartIp().String()
|
||||
input.GuestIpEnd = ipRange.EndIp().String()
|
||||
if ipRange != nil {
|
||||
input.GuestIpStart = ipRange.StartIp().String()
|
||||
input.GuestIpEnd = ipRange.EndIp().String()
|
||||
}
|
||||
|
||||
if ipRange6 != nil {
|
||||
// validate v6 ip addr
|
||||
@@ -3912,6 +3926,10 @@ func (net *SNetwork) PerformSyncAdditionalWires(
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (net *SNetwork) IsSupportIPv4() bool {
|
||||
return len(net.GuestIpStart) > 0 && len(net.GuestIpEnd) > 0
|
||||
}
|
||||
|
||||
func (net *SNetwork) IsSupportIPv6() bool {
|
||||
return len(net.GuestIp6Start) > 0 && len(net.GuestIp6End) > 0
|
||||
}
|
||||
|
||||
@@ -965,24 +965,26 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics
|
||||
cmds.WriteString("\n")
|
||||
} else if nicDesc.Manual {
|
||||
ifname := nicDesc.Name
|
||||
cmds.WriteString(fmt.Sprintf("iface %s inet static\n", nicDesc.Name))
|
||||
if nicDesc.VlanInterface {
|
||||
cmds.WriteString("\n")
|
||||
ifname = fmt.Sprintf("%s.%d", nicDesc.Name, nicDesc.Vlan)
|
||||
cmds.WriteString(fmt.Sprintf("auto %s\n", ifname))
|
||||
cmds.WriteString(fmt.Sprintf("iface %s inet static\n", ifname))
|
||||
if len(nicDesc.Ip) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf("iface %s inet static\n", nicDesc.Name))
|
||||
if nicDesc.VlanInterface {
|
||||
cmds.WriteString("\n")
|
||||
ifname = fmt.Sprintf("%s.%d", nicDesc.Name, nicDesc.Vlan)
|
||||
cmds.WriteString(fmt.Sprintf("auto %s\n", ifname))
|
||||
cmds.WriteString(fmt.Sprintf("iface %s inet static\n", ifname))
|
||||
}
|
||||
netmask := netutils2.Netlen2Mask(int(nicDesc.Masklen))
|
||||
cmds.WriteString(fmt.Sprintf(" address %s\n", nicDesc.Ip))
|
||||
cmds.WriteString(fmt.Sprintf(" netmask %s\n", netmask))
|
||||
cmds.WriteString(fmt.Sprintf(" hwaddress ether %s\n", nicDesc.Mac))
|
||||
if len(nicDesc.Gateway) > 0 && nicDesc.Ip == mainIp {
|
||||
cmds.WriteString(fmt.Sprintf(" gateway %s\n", nicDesc.Gateway))
|
||||
}
|
||||
if nicDesc.Mtu > 0 {
|
||||
cmds.WriteString(fmt.Sprintf(" mtu %d\n", nicDesc.Mtu))
|
||||
}
|
||||
}
|
||||
|
||||
netmask := netutils2.Netlen2Mask(int(nicDesc.Masklen))
|
||||
cmds.WriteString(fmt.Sprintf(" address %s\n", nicDesc.Ip))
|
||||
cmds.WriteString(fmt.Sprintf(" netmask %s\n", netmask))
|
||||
cmds.WriteString(fmt.Sprintf(" hwaddress ether %s\n", nicDesc.Mac))
|
||||
if len(nicDesc.Gateway) > 0 && nicDesc.Ip == mainIp {
|
||||
cmds.WriteString(fmt.Sprintf(" gateway %s\n", nicDesc.Gateway))
|
||||
}
|
||||
if nicDesc.Mtu > 0 {
|
||||
cmds.WriteString(fmt.Sprintf(" mtu %d\n", nicDesc.Mtu))
|
||||
}
|
||||
routes4 := make([]netutils2.SRouteInfo, 0)
|
||||
routes6 := make([]netutils2.SRouteInfo, 0)
|
||||
routes4, routes6 = netutils2.AddNicRoutes(routes4, routes6, nicDesc, mainIp, mainIp6, nicCnt)
|
||||
@@ -1002,11 +1004,24 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics
|
||||
cmds.WriteString(fmt.Sprintf(" dns-search %s\n", nicDesc.Domain))
|
||||
domains = append(domains, nicDesc.Domain)
|
||||
}
|
||||
if nicDesc.Mtu > 0 {
|
||||
cmds.WriteString(fmt.Sprintf(" mtu %d\n", nicDesc.Mtu))
|
||||
}
|
||||
dnslist := netutils2.GetNicDns(nicDesc)
|
||||
if len(dnslist) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf(" dns-nameservers %s\n", strings.Join(dnslist, " ")))
|
||||
dnss = append(dnss, dnslist...)
|
||||
if len(nicDesc.Domain) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf(" dns-search %s\n", nicDesc.Domain))
|
||||
domains = append(domains, nicDesc.Domain)
|
||||
}
|
||||
}
|
||||
if len(nicDesc.TeamingSlaves) > 0 {
|
||||
cmds.WriteString(getNicTeamingConfigCmds(nicDesc.TeamingSlaves))
|
||||
}
|
||||
cmds.WriteString("\n")
|
||||
}
|
||||
if len(nicDesc.TeamingSlaves) > 0 {
|
||||
cmds.WriteString(getNicTeamingConfigCmds(nicDesc.TeamingSlaves))
|
||||
}
|
||||
cmds.WriteString("\n")
|
||||
|
||||
if len(nicDesc.Ip6) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf("iface %s inet6 static\n", ifname))
|
||||
cmds.WriteString(fmt.Sprintf(" address %s\n", nicDesc.Ip6))
|
||||
@@ -1017,11 +1032,14 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics
|
||||
cmds.WriteString("\n")
|
||||
}
|
||||
} else {
|
||||
cmds.WriteString(fmt.Sprintf("iface %s inet dhcp\n", nicDesc.Name))
|
||||
if len(nicDesc.TeamingSlaves) > 0 {
|
||||
cmds.WriteString(getNicTeamingConfigCmds(nicDesc.TeamingSlaves))
|
||||
if len(nicDesc.Ip) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf("iface %s inet dhcp\n", nicDesc.Name))
|
||||
if len(nicDesc.TeamingSlaves) > 0 {
|
||||
cmds.WriteString(getNicTeamingConfigCmds(nicDesc.TeamingSlaves))
|
||||
}
|
||||
cmds.WriteString("\n")
|
||||
}
|
||||
cmds.WriteString("\n")
|
||||
|
||||
if len(nicDesc.Ip6) > 0 {
|
||||
// ipv6 support static temporarily
|
||||
// TODO
|
||||
@@ -1470,13 +1488,15 @@ func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics
|
||||
return errors.Wrap(err, "deployVlanNetworkingScripts")
|
||||
}
|
||||
} else {
|
||||
netmask := netutils2.Netlen2Mask(int(nicDesc.Masklen))
|
||||
cmds.WriteString("NETMASK=")
|
||||
cmds.WriteString(netmask)
|
||||
cmds.WriteString("\n")
|
||||
cmds.WriteString("IPADDR=")
|
||||
cmds.WriteString(nicDesc.Ip)
|
||||
cmds.WriteString("\n")
|
||||
if len(nicDesc.Ip) > 0 {
|
||||
netmask := netutils2.Netlen2Mask(int(nicDesc.Masklen))
|
||||
cmds.WriteString("NETMASK=")
|
||||
cmds.WriteString(netmask)
|
||||
cmds.WriteString("\n")
|
||||
cmds.WriteString("IPADDR=")
|
||||
cmds.WriteString(nicDesc.Ip)
|
||||
cmds.WriteString("\n")
|
||||
}
|
||||
if len(nicDesc.Gateway) > 0 && nicDesc.Ip == mainIp {
|
||||
cmds.WriteString("GATEWAY=")
|
||||
cmds.WriteString(nicDesc.Gateway)
|
||||
@@ -1500,17 +1520,18 @@ func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics
|
||||
if err := rootFs.FilePutContents(fn, rtblStr, false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dnslist := netutils2.GetNicDns(nicDesc)
|
||||
if len(dnslist) > 0 {
|
||||
cmds.WriteString("PEERDNS=yes\n")
|
||||
for i := 0; i < len(dnslist); i++ {
|
||||
cmds.WriteString(fmt.Sprintf("DNS%d=%s\n", i+1, dnslist[i]))
|
||||
}
|
||||
if len(nicDesc.Domain) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf("DOMAIN=%s\n", nicDesc.Domain))
|
||||
dnslist := netutils2.GetNicDns(nicDesc)
|
||||
if len(dnslist) > 0 {
|
||||
cmds.WriteString("PEERDNS=yes\n")
|
||||
for i := 0; i < len(dnslist); i++ {
|
||||
cmds.WriteString(fmt.Sprintf("DNS%d=%s\n", i+1, dnslist[i]))
|
||||
}
|
||||
if len(nicDesc.Domain) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf("DOMAIN=%s\n", nicDesc.Domain))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(nicDesc.Ip6) > 0 {
|
||||
cmds.WriteString("IPV6INIT=yes\n")
|
||||
cmds.WriteString("DHCPV6C=no\n")
|
||||
@@ -1522,17 +1543,20 @@ func (r *sRedhatLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cmds.WriteString("BOOTPROTO=dhcp\n")
|
||||
if len(nicDesc.Ip) > 0 {
|
||||
cmds.WriteString("BOOTPROTO=dhcp\n")
|
||||
}
|
||||
|
||||
if len(nicDesc.Ip6) > 0 {
|
||||
// IPv6 support static temporarily
|
||||
// TODO
|
||||
cmds.WriteString("IPV6INIT=yes\n")
|
||||
cmds.WriteString("DHCPV6C=yes\n")
|
||||
cmds.WriteString("IPV6_AUTOCONF=yes\n")
|
||||
// cmds.WriteString(fmt.Sprintf("IPV6ADDR=%s/%d\n", nicDesc.Ip6, nicDesc.Masklen6))
|
||||
// if len(nicDesc.Gateway6) > 0 {
|
||||
// cmds.WriteString("IPV6_DEFROUTE=yes\n", nicDesc.Gateway6))
|
||||
// }
|
||||
cmds.WriteString(fmt.Sprintf("IPV6ADDR=%s/%d\n", nicDesc.Ip6, nicDesc.Masklen6))
|
||||
if len(nicDesc.Gateway6) > 0 {
|
||||
cmds.WriteString("IPV6_DEFROUTE=yes\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
var fn = fmt.Sprintf("%s/ifcfg-%s", scriptPath, nicDesc.Name)
|
||||
|
||||
@@ -225,16 +225,23 @@ func (r *sSuseLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics []
|
||||
cmds.WriteString(netutils2.PSEUDO_VIP)
|
||||
cmds.WriteString("\n")
|
||||
} else if nicDesc.Manual {
|
||||
cmds.WriteString("STARTMODE=auto\n")
|
||||
cmds.WriteString("BOOTPROTO=static\n")
|
||||
cmds.WriteString(fmt.Sprintf("IPADDR=%s/%d\n", nicDesc.Ip, nicDesc.Masklen))
|
||||
if nicDesc.VlanInterface {
|
||||
if err := r.deployVlanNetworkingScripts(rootFs, "", mainIp, mainIp6, nicCnt, nicDesc); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
||||
if len(nicDesc.Ip6) > 0 {
|
||||
cmds.WriteString("IPV6INIT=yes\n")
|
||||
cmds.WriteString("IPV6_AUTOCONF=no\n")
|
||||
cmds.WriteString(fmt.Sprintf("IPADDR_V6=%s/%d\n", nicDesc.Ip6, nicDesc.Masklen6))
|
||||
cmds.WriteString("STARTMODE=auto\n")
|
||||
cmds.WriteString("BOOTPROTO=static\n")
|
||||
if len(nicDesc.Ip) > 0 {
|
||||
cmds.WriteString(fmt.Sprintf("IPADDR=%s/%d\n", nicDesc.Ip, nicDesc.Masklen))
|
||||
}
|
||||
if len(nicDesc.Ip6) > 0 {
|
||||
cmds.WriteString("IPV6INIT=yes\n")
|
||||
cmds.WriteString("IPV6_AUTOCONF=no\n")
|
||||
cmds.WriteString(fmt.Sprintf("IPADDR_V6=%s/%d\n", nicDesc.Ip6, nicDesc.Masklen6))
|
||||
}
|
||||
}
|
||||
|
||||
var routes4 = make([]netutils2.SRouteInfo, 0)
|
||||
var routes6 = make([]netutils2.SRouteInfo, 0)
|
||||
routes4, routes6 = netutils2.AddNicRoutes(routes4, routes6, nicDesc, mainIp, mainIp6, nicCnt)
|
||||
@@ -279,17 +286,21 @@ func (r *sSuseLikeRootFs) deployNetworkingScripts(rootFs IDiskPartition, nics []
|
||||
if err := rootFs.FilePutContents(fn, rtblStr, false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
dnslist := netutils2.GetNicDns(nicDesc)
|
||||
for i := 0; i < len(dnslist); i++ {
|
||||
if !utils.IsInArray(dnslist[i], dnsSrv) {
|
||||
dnsSrv = append(dnsSrv, dnslist[i])
|
||||
dnslist := netutils2.GetNicDns(nicDesc)
|
||||
for i := 0; i < len(dnslist); i++ {
|
||||
if !utils.IsInArray(dnslist[i], dnsSrv) {
|
||||
dnsSrv = append(dnsSrv, dnslist[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
cmds.WriteString("STARTMODE=auto\n")
|
||||
cmds.WriteString("BOOTPROTO=dhcp4\n")
|
||||
if len(nicDesc.Ip) > 0 {
|
||||
cmds.WriteString("BOOTPROTO=dhcp4\n")
|
||||
}
|
||||
|
||||
if len(nicDesc.Ip6) > 0 {
|
||||
// IPv6 support static temporarily
|
||||
// TODO
|
||||
|
||||
@@ -342,7 +342,7 @@ func (d *SBaseBridgeDriver) ConfirmToConfig() (bool, string, error) {
|
||||
if d.bridge.Addr != d.ip {
|
||||
return false, "", fmt.Errorf("bridge %s IP %s is not expected IP %s, mismatch", d.bridge, d.bridge.Addr, d.ip)
|
||||
}
|
||||
} else {
|
||||
} else if len(d.ip6) == 0 {
|
||||
if d.inter != nil && len(d.inter.Addr) > 0 {
|
||||
return false, "", fmt.Errorf("interface %s should have no address", d.inter)
|
||||
}
|
||||
@@ -429,14 +429,15 @@ func (d *SBaseBridgeDriver) SetupAddresses() error {
|
||||
addr string
|
||||
masklen int
|
||||
)
|
||||
if len(d.ip) == 0 {
|
||||
if len(d.ip) == 0 && len(d.ip6) == 0 {
|
||||
addr, masklen = netutils2.GetSecretInterfaceAddress()
|
||||
} else {
|
||||
addr = d.ip
|
||||
masklen = d.maskLen
|
||||
}
|
||||
addrStr := []string{
|
||||
fmt.Sprintf("%s/%d", addr, masklen),
|
||||
addrStr := []string{}
|
||||
if len(d.ip) > 0 {
|
||||
addrStr = append(addrStr, fmt.Sprintf("%s/%d", addr, masklen))
|
||||
}
|
||||
if len(d.ip6) > 0 {
|
||||
addrStr = append(addrStr, fmt.Sprintf("%s/%d", d.ip6, d.mask6Len))
|
||||
@@ -553,7 +554,7 @@ func addr2Prefix(addrStr string, maskLen int) string {
|
||||
func (d *SBaseBridgeDriver) Setup(o IBridgeDriver) error {
|
||||
var routes []iproute2.RouteSpec
|
||||
var slaveAddrs []netutils2.SNicAddress
|
||||
if d.inter != nil && len(d.inter.Addr) > 0 {
|
||||
if d.inter != nil && (len(d.inter.Addr) > 0 || len(d.inter.Addr6) > 0) {
|
||||
routes = d.inter.GetRouteSpecs()
|
||||
slaveAddrs = d.inter.GetSlaveAddresses()
|
||||
log.Infof("to migrate routes: %s slaveAddress: %s", jsonutils.Marshal(routes), jsonutils.Marshal(slaveAddrs))
|
||||
|
||||
@@ -394,14 +394,14 @@ func (h *SHostInfo) parseConfig() error {
|
||||
|
||||
if len(options.HostOptions.ListenInterface) > 0 {
|
||||
h.MasterNic = netutils2.NewNetInterface(options.HostOptions.ListenInterface)
|
||||
if len(h.MasterNic.Addr) == 0 {
|
||||
if len(h.MasterNic.Addr) == 0 && len(h.MasterNic.Addr6) == 0 {
|
||||
return fmt.Errorf("Listen interface %s master have no IP", options.HostOptions.ListenInterface)
|
||||
}
|
||||
} else {
|
||||
// set MasterNic to the first NIC with IP
|
||||
h.MasterNic = nil
|
||||
for _, n := range h.Nics {
|
||||
if len(n.Ip) > 0 {
|
||||
if len(n.Ip) > 0 || len(n.Ip6) > 0 {
|
||||
h.MasterNic = netutils2.NewNetInterface(n.Bridge)
|
||||
}
|
||||
}
|
||||
@@ -1135,12 +1135,19 @@ func (h *SHostInfo) detectOvsKOVersion() error {
|
||||
}
|
||||
|
||||
func (h *SHostInfo) GetMasterNicIpAndMask() (string, int) {
|
||||
mask, _ := h.MasterNic.Mask.Size()
|
||||
return h.MasterNic.Addr, mask
|
||||
if h.MasterNic.Addr != "" {
|
||||
mask, _ := h.MasterNic.Mask.Size()
|
||||
return h.MasterNic.Addr, mask
|
||||
}
|
||||
mask, _ := h.MasterNic.Mask6.Size()
|
||||
return h.MasterNic.Addr6, mask
|
||||
}
|
||||
|
||||
func (h *SHostInfo) GetMasterIp() string {
|
||||
return h.MasterNic.Addr
|
||||
if h.MasterNic.Addr != "" {
|
||||
return h.MasterNic.Addr
|
||||
}
|
||||
return h.MasterNic.Addr6
|
||||
}
|
||||
|
||||
func (h *SHostInfo) GetMasterMac() string {
|
||||
@@ -1421,12 +1428,12 @@ func (h *SHostInfo) initZoneInfo(zoneId string) error {
|
||||
func (h *SHostInfo) waitMasterNicIp() error {
|
||||
const maxWaitSeconds = 900
|
||||
waitSeconds := 0
|
||||
for h.MasterNic.Addr == "" && waitSeconds < maxWaitSeconds {
|
||||
for h.MasterNic.Addr == "" && h.MasterNic.Addr6 == "" && waitSeconds < maxWaitSeconds {
|
||||
time.Sleep(time.Second)
|
||||
waitSeconds++
|
||||
h.MasterNic.FetchConfig()
|
||||
}
|
||||
if h.MasterNic.Addr == "" {
|
||||
if h.MasterNic.Addr == "" && h.MasterNic.Addr6 == "" {
|
||||
return errors.Wrap(httperrors.ErrInvalidStatus, "fail to fetch master nic IP address")
|
||||
}
|
||||
if h.MasterNic.GetMac() == "" {
|
||||
@@ -1571,7 +1578,11 @@ func (h *SHostInfo) updateOrCreateHost(hostId string) (*api.HostDetails, error)
|
||||
if options.HostOptions.EnableSsl {
|
||||
schema = "https"
|
||||
}
|
||||
input.ManagerUri = fmt.Sprintf("%s://%s:%d", schema, masterIp, options.HostOptions.Port)
|
||||
if strings.Contains(masterIp, ":") {
|
||||
input.ManagerUri = fmt.Sprintf("%s://[%s]:%d", schema, masterIp, options.HostOptions.Port)
|
||||
} else {
|
||||
input.ManagerUri = fmt.Sprintf("%s://%s:%d", schema, masterIp, options.HostOptions.Port)
|
||||
}
|
||||
input.CpuCount = &h.Cpu.cpuInfoProc.Count
|
||||
nodeCount := int8(h.Cpu.cpuInfoDmi.Nodes)
|
||||
if sysutils.IsHypervisor() {
|
||||
|
||||
@@ -266,7 +266,7 @@ func NewNIC(desc string) (*SNIC, error) {
|
||||
nic.Ip6 = data[3]
|
||||
}
|
||||
} else if regutils.MatchIP6Addr(data[2]) {
|
||||
nic.Ip6 = data[3]
|
||||
nic.Ip6 = data[2]
|
||||
if len(data) > 3 && regutils.MatchIP4Addr(data[3]) {
|
||||
nic.Ip = data[3]
|
||||
}
|
||||
@@ -366,9 +366,11 @@ func NewNIC(desc string) (*SNIC, error) {
|
||||
}
|
||||
}
|
||||
|
||||
nic.dhcpServer, err = hostdhcp.NewGuestDHCPServer(nic.Bridge, options.HostOptions.DhcpServerPort, relayConf)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "NewGuestDHCPServer(%s, %d, %#v)", nic.Bridge, options.HostOptions.DhcpServerPort, relayConf)
|
||||
if len(nic.Ip) > 0 {
|
||||
nic.dhcpServer, err = hostdhcp.NewGuestDHCPServer(nic.Bridge, options.HostOptions.DhcpServerPort, relayConf)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "NewGuestDHCPServer(%s, %d, %#v)", nic.Bridge, options.HostOptions.DhcpServerPort, relayConf)
|
||||
}
|
||||
}
|
||||
|
||||
var relayConf6 *hostdhcp.SDHCPRelayUpstream
|
||||
@@ -382,9 +384,11 @@ func NewNIC(desc string) (*SNIC, error) {
|
||||
}
|
||||
}
|
||||
|
||||
nic.dhcpServer6, err = hostdhcp.NewGuestDHCP6Server(nic.Bridge, options.HostOptions.Dhcp6ServerPort, relayConf6)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "NewGuestDHCP6Server(%s, %d, %#v)", nic.Bridge, options.HostOptions.Dhcp6ServerPort, relayConf6)
|
||||
if len(nic.Ip6) > 0 {
|
||||
nic.dhcpServer6, err = hostdhcp.NewGuestDHCP6Server(nic.Bridge, options.HostOptions.Dhcp6ServerPort, relayConf6)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "NewGuestDHCP6Server(%s, %d, %#v)", nic.Bridge, options.HostOptions.Dhcp6ServerPort, relayConf6)
|
||||
}
|
||||
}
|
||||
// dhcp server start after guest manager init
|
||||
return nic, nil
|
||||
|
||||
@@ -293,7 +293,7 @@ func (s *STelegraf) GetConfig(kwargs map[string]interface{}) string {
|
||||
conf += "[[inputs.linux_sysctl_fs]]\n"
|
||||
conf += "\n"
|
||||
conf += "[[inputs.http_listener_v2]]\n"
|
||||
conf += " service_address = \"127.0.0.1:8087\"\n"
|
||||
conf += " service_address = \"localhost:8087\"\n"
|
||||
conf += " path = \"/write\"\n"
|
||||
conf += " data_source = \"body\"\n"
|
||||
conf += " data_format = \"influx\"\n"
|
||||
@@ -418,7 +418,7 @@ func (s *STelegraf) reloadTelegrafByDocker() error {
|
||||
}
|
||||
|
||||
func (s *STelegraf) reloadTelegrafByHTTP() error {
|
||||
telegrafReoladUrl := "http://127.0.0.1:8087/reload"
|
||||
telegrafReoladUrl := "http://localhost:8087/reload"
|
||||
log.Infof("Reloading telegraf by %q ...", telegrafReoladUrl)
|
||||
if _, _, err := httputils.JSONRequest(
|
||||
httputils.GetDefaultClient(), context.Background(),
|
||||
|
||||
@@ -67,9 +67,9 @@ func (opts *NetworkListOptions) Params() (jsonutils.JSONObject, error) {
|
||||
type NetworkCreateOptions struct {
|
||||
WIRE string `help:"ID or Name of wire in which the network is created"`
|
||||
NETWORK string `help:"Name of new network"`
|
||||
STARTIP string `help:"Start of IPv4 address range"`
|
||||
ENDIP string `help:"End of IPv4 address rnage"`
|
||||
NETMASK int64 `help:"Length of network mask"`
|
||||
StartIp string `help:"Start of IPv4 address range"`
|
||||
EndIp string `help:"End of IPv4 address rnage"`
|
||||
NetMask int64 `help:"Length of network mask"`
|
||||
Gateway string `help:"Default gateway"`
|
||||
|
||||
StartIp6 string `help:"IPv6 start ip"`
|
||||
@@ -91,9 +91,16 @@ func (opts *NetworkCreateOptions) Params() (jsonutils.JSONObject, error) {
|
||||
|
||||
params.Add(jsonutils.NewString(opts.WIRE), "wire")
|
||||
params.Add(jsonutils.NewString(opts.NETWORK), "name")
|
||||
params.Add(jsonutils.NewString(opts.STARTIP), "guest_ip_start")
|
||||
params.Add(jsonutils.NewString(opts.ENDIP), "guest_ip_end")
|
||||
params.Add(jsonutils.NewInt(opts.NETMASK), "guest_ip_mask")
|
||||
|
||||
if len(opts.StartIp) > 0 {
|
||||
params.Add(jsonutils.NewString(opts.StartIp), "guest_ip_start")
|
||||
}
|
||||
if len(opts.EndIp) > 0 {
|
||||
params.Add(jsonutils.NewString(opts.EndIp), "guest_ip_end")
|
||||
}
|
||||
if opts.NetMask > 0 {
|
||||
params.Add(jsonutils.NewInt(opts.NetMask), "guest_ip_mask")
|
||||
}
|
||||
if len(opts.Gateway) > 0 {
|
||||
params.Add(jsonutils.NewString(opts.Gateway), "guest_gateway")
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ const (
|
||||
ErrServerTypeIsNotMatch = `server type is not match`
|
||||
ErrExitIsNotMatch = `exit is not match`
|
||||
ErrWireIsNotMatch = `wire is not match`
|
||||
ErrNotSupportIpv6 = `not support ipv6`
|
||||
|
||||
ErrNoPorts = `no ports`
|
||||
ErrNotOwner = `not owner`
|
||||
|
||||
@@ -186,6 +186,12 @@ func IsNetworkAvailable(
|
||||
exit := req.Exit
|
||||
wire := req.Wire
|
||||
|
||||
if req.RequireIPv6 && !n.IsSupportIPv6() {
|
||||
return FailReason{
|
||||
Reason: fmt.Sprintf("%v(%v): %s", n.Name, n.Id, ErrNotSupportIpv6),
|
||||
}
|
||||
}
|
||||
|
||||
isMatchServerType := func(network *models.SNetwork) bool {
|
||||
return computeapi.IsInNetworkTypes(network.ServerType, netTypes)
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ func getIfaceIPs(iface *net.Interface) ([]net.IP, error) {
|
||||
if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
ips = append(ips, ipnet.IP)
|
||||
} else if ipnet.IP.To16() != nil {
|
||||
ips = append(ips, ipnet.IP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,195 @@ func MyIPTo(dstIP string) (ip string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func MyIPSmart() (ip string, err error) {
|
||||
return MyIPSmartTo("114.114.114.114", "2001:4860:4860::8888")
|
||||
}
|
||||
|
||||
func MyIPSmartTo(ipv4Target, ipv6Target string) (ip string, err error) {
|
||||
// try IPv4 connect
|
||||
if ipv4Target != "" {
|
||||
conn, err4 := net.Dial("udp4", ipv4Target+":53")
|
||||
if err4 == nil {
|
||||
defer conn.Close()
|
||||
if addr, ok := conn.LocalAddr().(*net.UDPAddr); ok {
|
||||
return addr.IP.String(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try IPv6 connect
|
||||
if ipv6Target != "" {
|
||||
conn, err6 := net.Dial("udp6", "["+ipv6Target+"]:53")
|
||||
if err6 == nil {
|
||||
defer conn.Close()
|
||||
if addr, ok := conn.LocalAddr().(*net.UDPAddr); ok {
|
||||
return addr.IP.String(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try locallink
|
||||
return getLocalIP()
|
||||
}
|
||||
|
||||
func getLocalIP() (string, error) {
|
||||
// get default route
|
||||
if ip := getIPFromDefaultRoute(); ip != "" {
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "get network interfaces")
|
||||
}
|
||||
|
||||
var candidateIPs []string
|
||||
for _, iface := range interfaces {
|
||||
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
return ipnet.IP.String(), nil
|
||||
} else if ipnet.IP.To16() != nil && !ipnet.IP.IsLinkLocalUnicast() {
|
||||
candidateIPs = append(candidateIPs, ipnet.IP.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(candidateIPs) > 0 {
|
||||
return candidateIPs[0], nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("no suitable IP address found")
|
||||
}
|
||||
|
||||
func getIPFromDefaultRoute() string {
|
||||
if ip := getIPFromDefaultRouteV4(); ip != "" {
|
||||
return ip
|
||||
}
|
||||
|
||||
if ip := getIPFromDefaultRouteV6(); ip != "" {
|
||||
return ip
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func getIPFromDefaultRouteV4() string {
|
||||
output, err := procutils.NewCommand("ip", "route", "show", "default").Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, "default") && strings.Contains(line, "src") {
|
||||
fields := strings.Fields(line)
|
||||
for i, field := range fields {
|
||||
if field == "src" && i+1 < len(fields) {
|
||||
return fields[i+1]
|
||||
}
|
||||
}
|
||||
}
|
||||
if strings.Contains(line, "default") && strings.Contains(line, "dev") {
|
||||
fields := strings.Fields(line)
|
||||
for i, field := range fields {
|
||||
if field == "dev" && i+1 < len(fields) {
|
||||
if ip := getIPFromInterface(fields[i+1]); ip != "" {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func getIPFromDefaultRouteV6() string {
|
||||
output, err := procutils.NewCommand("ip", "-6", "route", "show", "default").Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, "default") && strings.Contains(line, "src") {
|
||||
fields := strings.Fields(line)
|
||||
for i, field := range fields {
|
||||
if field == "src" && i+1 < len(fields) {
|
||||
return fields[i+1]
|
||||
}
|
||||
}
|
||||
}
|
||||
if strings.Contains(line, "default") && strings.Contains(line, "dev") {
|
||||
fields := strings.Fields(line)
|
||||
for i, field := range fields {
|
||||
if field == "dev" && i+1 < len(fields) {
|
||||
if ip := getIPFromInterfaceV6(fields[i+1]); ip != "" {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func getIPFromInterface(ifaceName string) string {
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipv4 := ipnet.IP.To4(); ipv4 != nil {
|
||||
return ipv4.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func getIPFromInterfaceV6(ifaceName string) string {
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipv6 := ipnet.IP.To16(); ipv6 != nil && ipnet.IP.To4() == nil && !ipnet.IP.IsLinkLocalUnicast() {
|
||||
return ipv6.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetPrivatePrefixes(privatePrefixes []string) []string {
|
||||
if privatePrefixes != nil {
|
||||
return privatePrefixes
|
||||
|
||||
@@ -76,9 +76,12 @@ func (n *SNetInterface) GetRouteSpecs() []iproute2.RouteSpec {
|
||||
}
|
||||
routes6 := getRouteSpecs(routeList.List6)
|
||||
for i := range routes6 {
|
||||
if routes6[i].Gw == nil {
|
||||
isDefaultRoute := routes6[i].Dst.String() == "::/0"
|
||||
|
||||
if !isDefaultRoute && routes6[i].Gw == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(routes6[i].Dst.String(), "fe80:") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -73,9 +73,17 @@ func mustPrepOvsdbConfig(opts SOvnOptions) {
|
||||
)
|
||||
switch {
|
||||
case strings.HasPrefix(meth, "can-reach:"):
|
||||
encapIp, err = netutils2.MyIPTo(meth[10:])
|
||||
target := meth[10:]
|
||||
if strings.Contains(target, ":") {
|
||||
encapIp, err = netutils2.MyIPSmartTo("", target)
|
||||
} else {
|
||||
encapIp, err = netutils2.MyIPSmartTo(target, "")
|
||||
}
|
||||
default:
|
||||
encapIp, err = netutils2.MyIP()
|
||||
encapIp, err = netutils2.MyIPSmart()
|
||||
if err != nil {
|
||||
encapIp, err = netutils2.MyIP()
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
panic(errors.Wrapf(ErrOvnConfig, "determine encap ip, method: %q: %v", meth, err))
|
||||
|
||||
Vendored
+1
-1
@@ -1949,7 +1949,7 @@ yunion.io/x/log/hooks
|
||||
yunion.io/x/ovsdb/cli_util
|
||||
yunion.io/x/ovsdb/schema/ovn_nb
|
||||
yunion.io/x/ovsdb/types
|
||||
# yunion.io/x/pkg v1.10.4-0.20250712095850-7797c1f3ffa6
|
||||
# yunion.io/x/pkg v1.10.4-0.20250715023532-99a31ea00303
|
||||
## explicit; go 1.18
|
||||
yunion.io/x/pkg/appctx
|
||||
yunion.io/x/pkg/errors
|
||||
|
||||
+18
@@ -17,6 +17,7 @@ package netutils
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"net"
|
||||
"sort"
|
||||
@@ -400,6 +401,23 @@ func (ar IPV6AddrRange) ContainsRange(ar2 IPV6AddrRange) bool {
|
||||
return ar.start.Le(ar2.start) && ar.end.Ge(ar2.end)
|
||||
}
|
||||
|
||||
func Uint16ArrayToBigInt(ip [8]uint16) *big.Int {
|
||||
result := new(big.Int)
|
||||
for i := 0; i < 8; i++ {
|
||||
result.Lsh(result, 16)
|
||||
result.Add(result, big.NewInt(int64(ip[i])))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (ar IPV6AddrRange) AddressCount() *big.Int {
|
||||
start := Uint16ArrayToBigInt(ar.start)
|
||||
end := Uint16ArrayToBigInt(ar.end)
|
||||
diff := new(big.Int).Sub(end, start)
|
||||
diff.Add(diff, big.NewInt(1))
|
||||
return diff
|
||||
}
|
||||
|
||||
const (
|
||||
borderEqual = 0
|
||||
borderLower = 1
|
||||
|
||||
+51
-5
@@ -578,23 +578,69 @@ func TransSQLAchemyURL(pySQLSrc string) (dialect, ret string, err error) {
|
||||
}
|
||||
|
||||
lastAtIndex := strings.LastIndex(pySQLSrc, "@")
|
||||
if lastAtIndex == -1 {
|
||||
err = fmt.Errorf("Incorrect mysql connection url: %s", pySQLSrc)
|
||||
return
|
||||
}
|
||||
|
||||
firstPart := pySQLSrc[:lastAtIndex]
|
||||
secondPart := pySQLSrc[lastAtIndex+1:]
|
||||
|
||||
r := regexp.MustCompile(`[/:]+`)
|
||||
firstPartArr := r.Split(firstPart, -1)
|
||||
secondPartArr := r.Split(secondPart, -1)
|
||||
|
||||
strs := append(firstPartArr, secondPartArr...)
|
||||
if len(strs) != 6 {
|
||||
if len(firstPartArr) < 3 {
|
||||
err = fmt.Errorf("Incorrect mysql connection url: %s", pySQLSrc)
|
||||
return
|
||||
}
|
||||
user, passwd, host, port, dburl := strs[1], strs[2], strs[3], strs[4], strs[5]
|
||||
|
||||
user := firstPartArr[1]
|
||||
passwd := firstPartArr[2]
|
||||
|
||||
var host, port, dburl string
|
||||
if strings.HasPrefix(secondPart, "[") {
|
||||
endBracket := strings.Index(secondPart, "]")
|
||||
if endBracket == -1 {
|
||||
err = fmt.Errorf("Incorrect IPv6 address format: %s", pySQLSrc)
|
||||
return
|
||||
}
|
||||
|
||||
host = secondPart[:endBracket+1]
|
||||
remaining := secondPart[endBracket+1:]
|
||||
if !strings.HasPrefix(remaining, ":") {
|
||||
err = fmt.Errorf("Incorrect mysql connection url: %s", pySQLSrc)
|
||||
return
|
||||
}
|
||||
remaining = remaining[1:]
|
||||
slashIndex := strings.Index(remaining, "/")
|
||||
if slashIndex == -1 {
|
||||
err = fmt.Errorf("Incorrect mysql connection url: %s", pySQLSrc)
|
||||
return
|
||||
}
|
||||
port = remaining[:slashIndex]
|
||||
dburl = remaining[slashIndex+1:]
|
||||
} else {
|
||||
colonIndex := strings.Index(secondPart, ":")
|
||||
if colonIndex == -1 {
|
||||
err = fmt.Errorf("Incorrect mysql connection url: %s", pySQLSrc)
|
||||
return
|
||||
}
|
||||
|
||||
host = secondPart[:colonIndex]
|
||||
remaining := secondPart[colonIndex+1:]
|
||||
slashIndex := strings.Index(remaining, "/")
|
||||
if slashIndex == -1 {
|
||||
err = fmt.Errorf("Incorrect mysql connection url: %s", pySQLSrc)
|
||||
return
|
||||
}
|
||||
port = remaining[:slashIndex]
|
||||
dburl = remaining[slashIndex+1:]
|
||||
}
|
||||
|
||||
dburl, err = transMysqlQuery(dburl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ret = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", user, passwd, host, port, dburl)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user