mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-30 17:13:08 +08:00
fix: host network ipv6 support (#23013)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
@@ -263,6 +263,7 @@ func init() {
|
||||
INDEX int64 `help:"nic index"`
|
||||
Type string `help:"Nic type" choices:"admin|ipmi"`
|
||||
IpAddr string `help:"IP address"`
|
||||
Ip6Addr string `help:"IPv6 address"`
|
||||
Bridge string `help:"Bridge of hostwire"`
|
||||
Interface string `help:"Interface name, eg:eth0, en0"`
|
||||
}
|
||||
@@ -278,6 +279,9 @@ func init() {
|
||||
if len(args.IpAddr) > 0 {
|
||||
params.Add(jsonutils.NewString(args.IpAddr), "ip_addr")
|
||||
}
|
||||
if len(args.Ip6Addr) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ip6Addr), "ip6_addr")
|
||||
}
|
||||
if len(args.Bridge) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Bridge), "bridge")
|
||||
}
|
||||
@@ -310,7 +314,8 @@ func init() {
|
||||
type HostEnableNetIfOptions struct {
|
||||
ID string `help:"ID or Name of host"`
|
||||
MAC string `help:"MAC of NIC to enable"`
|
||||
Ip string `help:"IP address"`
|
||||
Ip string `help:"IPv4 address"`
|
||||
Ip6 string `help:"IPv6 address"`
|
||||
Network string `help:"network to connect"`
|
||||
Reserved bool `help:"fetch IP from reserved pool"`
|
||||
}
|
||||
@@ -319,6 +324,11 @@ func init() {
|
||||
params.Add(jsonutils.NewString(args.MAC), "mac")
|
||||
if len(args.Ip) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ip), "ip_addr")
|
||||
}
|
||||
if len(args.Ip6) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ip6), "ip6_addr")
|
||||
}
|
||||
if len(args.Ip) > 0 || len(args.Ip6) > 0 {
|
||||
if args.Reserved {
|
||||
params.Add(jsonutils.JSONTrue, "reserve")
|
||||
}
|
||||
|
||||
@@ -127,6 +127,8 @@ type GuestnetworkBaseDesc struct {
|
||||
Id string `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
MappedIpAddr string `json:"mapped_ip_addr"`
|
||||
|
||||
MappedIp6Addr string `json:"mapped_ip6_addr"`
|
||||
} `json:"vpc"`
|
||||
|
||||
Networkaddresses jsonutils.JSONObject `json:"networkaddresses"`
|
||||
|
||||
@@ -672,6 +672,12 @@ type HostAddNetifInput struct {
|
||||
Reserve *bool `json:"reserve"`
|
||||
|
||||
RequireDesignatedIp *bool `json:"require_designated_ip"`
|
||||
|
||||
Ip6Addr string `json:"ip6_addr"`
|
||||
|
||||
RequireIpv6 *bool `json:"require_ipv6"`
|
||||
|
||||
StrictIpv6 *bool `json:"strict_ipv6"`
|
||||
}
|
||||
|
||||
type HostEnableNetifInput struct {
|
||||
@@ -690,6 +696,12 @@ type HostEnableNetifInput struct {
|
||||
Reserve *bool `json:"reserve"`
|
||||
|
||||
RequireDesignatedIp *bool `json:"require_designated_ip"`
|
||||
|
||||
Ip6Addr string `json:"ip6_addr"`
|
||||
|
||||
RequireIpv6 *bool `json:"require_ipv6"`
|
||||
|
||||
StrictIpv6 *bool `json:"strict_ipv6"`
|
||||
}
|
||||
|
||||
type HostDisableNetifInput struct {
|
||||
|
||||
@@ -168,6 +168,7 @@ type NetworkTopologyOutput struct {
|
||||
|
||||
type HostnetworkTopologyOutput struct {
|
||||
IpAddr string `json:"ip_addr"`
|
||||
Ip6Addr string `json:"ip6_addr"`
|
||||
MacAddr string `json:"mac_addr"`
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ package compute
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
@@ -51,12 +52,22 @@ const (
|
||||
sVpcInterExtIP2 = "100.65.0.2"
|
||||
VpcInterExtMac1 = "ee:ee:ee:ee:ee:f0"
|
||||
VpcInterExtMac2 = "ee:ee:ee:ee:ee:f1"
|
||||
|
||||
sVpcInterCidr6 = "fc00::fffe:100:65:0:0/100"
|
||||
sVpcInterExtCidr6 = "fc00::fffe:100:65:0:0/112"
|
||||
VpcInterExtMask6 = 112
|
||||
sVpcInterExtIP16 = "fc00::fffe:100:65:0:1"
|
||||
sVpcInterExtIP26 = "fc00::fffe:100:65:0:2"
|
||||
)
|
||||
|
||||
var (
|
||||
vpcInterCidr netutils.IPV4Prefix
|
||||
vpcInterExtIP1 netutils.IPV4Addr
|
||||
vpcInterExtIP2 netutils.IPV4Addr
|
||||
|
||||
vpcInterCidr6 netutils.IPV6Prefix
|
||||
vpcInterExtIP16 netutils.IPV6Addr
|
||||
vpcInterExtIP26 netutils.IPV6Addr
|
||||
)
|
||||
|
||||
func VpcInterCidr() netutils.IPV4Prefix {
|
||||
@@ -71,12 +82,28 @@ func VpcInterExtIP2() netutils.IPV4Addr {
|
||||
return vpcInterExtIP2
|
||||
}
|
||||
|
||||
func VpcInterCidr6() netutils.IPV6Prefix {
|
||||
return vpcInterCidr6
|
||||
}
|
||||
|
||||
func VpcInterExtIP16() netutils.IPV6Addr {
|
||||
return vpcInterExtIP16
|
||||
}
|
||||
|
||||
func VpcInterExtIP26() netutils.IPV6Addr {
|
||||
return vpcInterExtIP26
|
||||
}
|
||||
|
||||
const (
|
||||
sVpcMappedCidr = "100.64.0.0/17"
|
||||
VpcMappedIPMask = 17
|
||||
sVpcMappedGatewayIP = "100.64.0.1"
|
||||
VpcMappedGatewayMac = "ee:ee:ee:ee:ee:ee"
|
||||
|
||||
sVpcMappedCidr6 = "fc00::fffe:100:64:0:0/100"
|
||||
VpcMappedIPMask6 = 100
|
||||
sVpcMappedGatewayIP6 = "fc00::fffe:100:64:0:1"
|
||||
|
||||
// reserved: [100.64.0.2, 100.64.0.127]
|
||||
|
||||
// [128, 2176 (128+2048)]
|
||||
@@ -98,18 +125,31 @@ const (
|
||||
sVpcEipGatewayIP = "100.64.128.2"
|
||||
VpcEipGatewayMac = "ee:ee:ee:ee:ee:ef"
|
||||
|
||||
sVpcEipGatewayCidr6 = "fc00::fffe:100:64:f000:0/100"
|
||||
VpcEipGatewayIPMask6 = 100
|
||||
sVpcEipGatewayIP6 = "fc00::fffe:100:64:f000:2"
|
||||
|
||||
sVpcEipGatewayIP3 = "100.64.128.3"
|
||||
VpcEipGatewayMac3 = "ee:ee:ee:ee:ee:f0"
|
||||
|
||||
sVpcEipGatewayIP63 = "fc00::fffe:100:64:f000:3"
|
||||
)
|
||||
|
||||
var (
|
||||
vpcMappedCidr netutils.IPV4Prefix
|
||||
vpcMappedGatewayIP netutils.IPV4Addr
|
||||
|
||||
vpcMappedCidr6 netutils.IPV6Prefix
|
||||
vpcMappedGatewayIP6 netutils.IPV6Addr
|
||||
|
||||
vpcEipGatewayCidr netutils.IPV4Prefix
|
||||
vpcEipGatewayIP netutils.IPV4Addr
|
||||
vpcEipGatewayIP3 netutils.IPV4Addr
|
||||
|
||||
vpcEipGatewayCidr6 netutils.IPV6Prefix
|
||||
vpcEipGatewayIP6 netutils.IPV6Addr
|
||||
vpcEipGatewayIP63 netutils.IPV6Addr
|
||||
|
||||
vpcMappedHostIPStart netutils.IPV4Addr
|
||||
vpcMappedHostIPEnd netutils.IPV4Addr
|
||||
|
||||
@@ -131,17 +171,41 @@ func init() {
|
||||
return v
|
||||
}
|
||||
|
||||
mi6 := func(v netutils.IPV6Addr, err error) netutils.IPV6Addr {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return v
|
||||
}
|
||||
mp6 := func(v netutils.IPV6Prefix, err error) netutils.IPV6Prefix {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
vpcInterCidr = mp(netutils.NewIPV4Prefix(sVpcInterCidr))
|
||||
vpcInterExtIP1 = mi(netutils.NewIPV4Addr(sVpcInterExtIP1))
|
||||
vpcInterExtIP2 = mi(netutils.NewIPV4Addr(sVpcInterExtIP2))
|
||||
|
||||
vpcInterCidr6 = mp6(netutils.NewIPV6Prefix(sVpcInterCidr6))
|
||||
vpcInterExtIP16 = mi6(netutils.NewIPV6Addr(sVpcInterExtIP16))
|
||||
vpcInterExtIP26 = mi6(netutils.NewIPV6Addr(sVpcInterExtIP26))
|
||||
|
||||
vpcMappedCidr = mp(netutils.NewIPV4Prefix(sVpcMappedCidr))
|
||||
vpcMappedGatewayIP = mi(netutils.NewIPV4Addr(sVpcMappedGatewayIP))
|
||||
|
||||
vpcMappedCidr6 = mp6(netutils.NewIPV6Prefix(sVpcMappedCidr6))
|
||||
vpcMappedGatewayIP6 = mi6(netutils.NewIPV6Addr(sVpcMappedGatewayIP6))
|
||||
|
||||
vpcEipGatewayCidr = mp(netutils.NewIPV4Prefix(sVpcEipGatewayCidr))
|
||||
vpcEipGatewayIP = mi(netutils.NewIPV4Addr(sVpcEipGatewayIP))
|
||||
vpcEipGatewayIP3 = mi(netutils.NewIPV4Addr(sVpcEipGatewayIP3))
|
||||
|
||||
vpcEipGatewayCidr6 = mp6(netutils.NewIPV6Prefix(sVpcEipGatewayCidr6))
|
||||
vpcEipGatewayIP6 = mi6(netutils.NewIPV6Addr(sVpcEipGatewayIP6))
|
||||
vpcEipGatewayIP63 = mi6(netutils.NewIPV6Addr(sVpcEipGatewayIP63))
|
||||
|
||||
vpcMappedHostIPStart = mi(netutils.NewIPV4Addr(sVpcMappedHostIPStart))
|
||||
vpcMappedHostIPEnd = mi(netutils.NewIPV4Addr(sVpcMappedHostIPEnd))
|
||||
|
||||
@@ -153,22 +217,42 @@ func VpcMappedCidr() netutils.IPV4Prefix {
|
||||
return vpcMappedCidr
|
||||
}
|
||||
|
||||
func VpcMappedCidr6() netutils.IPV6Prefix {
|
||||
return vpcMappedCidr6
|
||||
}
|
||||
|
||||
func VpcMappedGatewayIP() netutils.IPV4Addr {
|
||||
return vpcMappedGatewayIP
|
||||
}
|
||||
|
||||
func VpcMappedGatewayIP6() netutils.IPV6Addr {
|
||||
return vpcMappedGatewayIP6
|
||||
}
|
||||
|
||||
func VpcEipGatewayCidr() netutils.IPV4Prefix {
|
||||
return vpcEipGatewayCidr
|
||||
}
|
||||
|
||||
func VpcEipGatewayCidr6() netutils.IPV6Prefix {
|
||||
return vpcEipGatewayCidr6
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP() netutils.IPV4Addr {
|
||||
return vpcEipGatewayIP
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP6() netutils.IPV6Addr {
|
||||
return vpcEipGatewayIP6
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP3() netutils.IPV4Addr {
|
||||
return vpcEipGatewayIP3
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP63() netutils.IPV6Addr {
|
||||
return vpcEipGatewayIP63
|
||||
}
|
||||
|
||||
func VpcMappedHostIPStart() netutils.IPV4Addr {
|
||||
return vpcMappedHostIPStart
|
||||
}
|
||||
@@ -188,3 +272,8 @@ func VpcMappedIPEnd() netutils.IPV4Addr {
|
||||
func VpcOvnEncapCostStr() string {
|
||||
return fmt.Sprintf("%d", VPC_OVN_ENCAP_COST)
|
||||
}
|
||||
|
||||
func GenVpcMappedIP6(ip string) string {
|
||||
segs := strings.Split(ip, ".")
|
||||
return fmt.Sprintf("fc00::fffe:100:64:%s:%s", segs[2], segs[3])
|
||||
}
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ const (
|
||||
SKU_STATUS_AVAILABLE = "available"
|
||||
SKU_STATUS_SOLDOUT = "soldout"
|
||||
|
||||
MetaServiceMonitorAgentUrl = "http://169.254.169.254/monitor"
|
||||
MetaServiceMonitorAgentUrl = "http://%s/monitor"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -115,12 +115,12 @@ func GetNicDHCPConfig(
|
||||
conf.Gateway = net.ParseIP(n.Gateway)
|
||||
}
|
||||
if n.Ip6Addr != "" {
|
||||
ipAddr6, err := netutils.NewIPV6Addr(n.Ip6Addr)
|
||||
ip6Addr, err := netutils.NewIPV6Addr(n.Ip6Addr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Parse IPv6 address error: %q", n.Ip6Addr)
|
||||
}
|
||||
|
||||
conf.ClientIP6 = net.ParseIP(ipAddr6.String())
|
||||
conf.ClientIP6 = net.ParseIP(ip6Addr.String())
|
||||
conf.PrefixLen6 = n.Masklen6
|
||||
conf.Gateway6 = net.ParseIP(n.Gateway6)
|
||||
}
|
||||
|
||||
@@ -163,9 +163,10 @@ func (self *SBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *models.SG
|
||||
reuseAddr := false
|
||||
hn := host.GetAttach2Network(netConfig.Network)
|
||||
if hn != nil && options.Options.BaremetalServerReuseHostIp {
|
||||
if netConfig.Address == "" || netConfig.Address == hn.IpAddr {
|
||||
if (netConfig.Address == "" && netConfig.Address6 == "") || (netConfig.Address == hn.IpAddr && netConfig.Address6 == hn.Ip6Addr) {
|
||||
// try to reuse host network IP address
|
||||
netConfig.Address = hn.IpAddr
|
||||
netConfig.Address6 = hn.Ip6Addr
|
||||
reuseAddr = true
|
||||
}
|
||||
}
|
||||
@@ -248,17 +249,20 @@ func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ct
|
||||
nicConfs = append(nicConfs, nicConf)
|
||||
}
|
||||
address := ""
|
||||
address6 := ""
|
||||
reuseAddr := false
|
||||
hn := host.GetAttach2Network(net.Id)
|
||||
if hn != nil && options.Options.BaremetalServerReuseHostIp {
|
||||
// try to reuse host network IP address
|
||||
address = hn.IpAddr
|
||||
address6 = hn.Ip6Addr
|
||||
reuseAddr = true
|
||||
}
|
||||
return guest.Attach2Network(ctx, userCred, models.Attach2NetworkArgs{
|
||||
Network: net,
|
||||
PendingUsage: pendingUsage,
|
||||
IpAddr: address,
|
||||
Ip6Addr: address6,
|
||||
NicDriver: netConfig.Driver,
|
||||
BwLimit: netConfig.BwLimit,
|
||||
Virtual: netConfig.Vip,
|
||||
|
||||
@@ -163,9 +163,10 @@ func (self *SCloudpodsBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *
|
||||
reuseAddr := false
|
||||
hn := host.GetAttach2Network(netConfig.Network)
|
||||
if hn != nil && options.Options.BaremetalServerReuseHostIp {
|
||||
if netConfig.Address == "" || netConfig.Address == hn.IpAddr {
|
||||
if (netConfig.Address == "" && netConfig.Address6 == "") || (netConfig.Address == hn.IpAddr && netConfig.Address6 == hn.Ip6Addr) {
|
||||
// try to reuse host network IP address
|
||||
netConfig.Address = hn.IpAddr
|
||||
netConfig.Address6 = hn.Ip6Addr
|
||||
reuseAddr = true
|
||||
}
|
||||
}
|
||||
@@ -248,17 +249,20 @@ func (self *SCloudpodsBaremetalGuestDriver) Attach2RandomNetwork(guest *models.S
|
||||
nicConfs = append(nicConfs, nicConf)
|
||||
}
|
||||
address := ""
|
||||
address6 := ""
|
||||
reuseAddr := false
|
||||
hn := host.GetAttach2Network(net.Id)
|
||||
if hn != nil && options.Options.BaremetalServerReuseHostIp {
|
||||
// try to reuse host network IP address
|
||||
address = hn.IpAddr
|
||||
address6 = hn.Ip6Addr
|
||||
reuseAddr = true
|
||||
}
|
||||
return guest.Attach2Network(ctx, userCred, models.Attach2NetworkArgs{
|
||||
Network: net,
|
||||
PendingUsage: pendingUsage,
|
||||
IpAddr: address,
|
||||
Ip6Addr: address6,
|
||||
NicDriver: netConfig.Driver,
|
||||
BwLimit: netConfig.BwLimit,
|
||||
Virtual: netConfig.Vip,
|
||||
|
||||
@@ -1203,7 +1203,17 @@ func (self *SKVMGuestDriver) RequestQgaCommand(ctx context.Context, userCred mcc
|
||||
|
||||
func (self *SKVMGuestDriver) FetchMonitorUrl(ctx context.Context, guest *models.SGuest) string {
|
||||
if options.Options.KvmMonitorAgentUseMetadataService && !guest.IsSriov() {
|
||||
return apis.MetaServiceMonitorAgentUrl
|
||||
var metadataIp string
|
||||
strictIpv6, err := guest.IsStrictIpv6()
|
||||
if err != nil {
|
||||
log.Errorf("IsStrictIpv6 for guest %s error: %v", guest.Id, err)
|
||||
}
|
||||
if strictIpv6 {
|
||||
metadataIp = "[" + options.Options.MetadataServerIp6s[0] + "]"
|
||||
} else {
|
||||
metadataIp = options.Options.MetadataServerIp4s[0]
|
||||
}
|
||||
return fmt.Sprintf(apis.MetaServiceMonitorAgentUrl, metadataIp)
|
||||
}
|
||||
return self.SVirtualizedGuestDriver.FetchMonitorUrl(ctx, guest)
|
||||
}
|
||||
|
||||
@@ -139,8 +139,12 @@ func (self *SBaseHostDriver) FinishUnconvert(ctx context.Context, userCred mccli
|
||||
if adminNic == nil {
|
||||
return fmt.Errorf("admin nic is nil")
|
||||
}
|
||||
accessIp := adminNic.IpAddr
|
||||
if accessIp == "" {
|
||||
accessIp = adminNic.Ip6Addr
|
||||
}
|
||||
db.Update(host, func() error {
|
||||
host.AccessIp = adminNic.IpAddr
|
||||
host.AccessIp = accessIp
|
||||
host.SetEnabled(true)
|
||||
host.HostType = api.HOST_TYPE_BAREMETAL
|
||||
host.HostStatus = api.HOST_OFFLINE
|
||||
|
||||
@@ -64,7 +64,7 @@ type SGroupnetwork struct {
|
||||
// IPv6地址
|
||||
Ip6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user" create:"optional"` // Column(VARCHAR(64, charset='ascii'), nullable=True)
|
||||
|
||||
Index int8 `nullable:"false" default:"0" list:"user" list:"user" update:"user" create:"optional"` // Column(TINYINT, nullable=False, default=0)
|
||||
Index int8 `nullable:"false" default:"0" list:"user" update:"user" create:"optional"` // Column(TINYINT, nullable=False, default=0)
|
||||
|
||||
EipId string `width:"36" charset:"ascii" nullable:"true" list:"user"` // Column(VARCHAR(36, charset='ascii'), nullable=True)
|
||||
}
|
||||
|
||||
@@ -649,13 +649,13 @@ func (grp *SGroup) PerformAttachnetwork(ctx context.Context, userCred mcclient.T
|
||||
return nil, errors.Wrapf(httperrors.ErrConflict, "candidate ip %s is occupied!", input.IpAddr)
|
||||
}
|
||||
|
||||
var ipAddr6 string
|
||||
var ip6Addr string
|
||||
if len(input.Ip6Addr) > 0 || input.RequireIPv6 {
|
||||
ipAddr6, err = net.GetFreeIP(ctx, userCred, nil, nil, input.Ip6Addr, input.AllocDir, input.Reserved != nil && *input.Reserved, api.AddressTypeIPv6)
|
||||
ip6Addr, err = net.GetFreeIP(ctx, userCred, nil, nil, input.Ip6Addr, input.AllocDir, input.Reserved != nil && *input.Reserved, api.AddressTypeIPv6)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetFreeIPv6")
|
||||
}
|
||||
if len(input.Ip6Addr) > 0 && ipAddr6 != input.Ip6Addr && input.RequireDesignatedIp != nil && *input.RequireDesignatedIp {
|
||||
if len(input.Ip6Addr) > 0 && ip6Addr != input.Ip6Addr && input.RequireDesignatedIp != nil && *input.RequireDesignatedIp {
|
||||
return nil, errors.Wrapf(httperrors.ErrConflict, "candidate v6 ip %s is occupied!", input.Ip6Addr)
|
||||
}
|
||||
}
|
||||
@@ -664,7 +664,7 @@ func (grp *SGroup) PerformAttachnetwork(ctx context.Context, userCred mcclient.T
|
||||
gn.NetworkId = net.Id
|
||||
gn.GroupId = grp.Id
|
||||
gn.IpAddr = ipAddr
|
||||
gn.Ip6Addr = ipAddr6
|
||||
gn.Ip6Addr = ip6Addr
|
||||
|
||||
gn.SetModelManager(GroupnetworkManager, &gn)
|
||||
|
||||
|
||||
@@ -125,7 +125,8 @@ func (guest *SGuest) PerformMigrateNetwork(ctx context.Context, userCred mcclien
|
||||
// perform the database change
|
||||
_, err = db.Update(&srcNic, func() error {
|
||||
srcNic.NetworkId = destNet.Id
|
||||
srcNic.MappedIpAddr = "" // reset MappedIpAddr anyway
|
||||
srcNic.MappedIpAddr = "" // reset MappedIpAddr anyway
|
||||
srcNic.MappedIp6Addr = "" // reset MappedIp6Addr anyway
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -112,6 +112,8 @@ type SGuestnetwork struct {
|
||||
|
||||
// IPv4映射地址,当子网属于私有云vpc的时候分配,用于访问外网
|
||||
MappedIpAddr string `width:"16" charset:"ascii" nullable:"true" list:"user"`
|
||||
// IPv6映射地址,当子网属于私有云vpc的时候分配,用于访问外网
|
||||
MappedIp6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user"`
|
||||
|
||||
// 网卡关联的Eip实例
|
||||
EipId string `width:"36" charset:"ascii" nullable:"true" list:"user"`
|
||||
@@ -359,18 +361,8 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
gn.IpAddr = ipAddr
|
||||
}
|
||||
}
|
||||
|
||||
if vpc.Id != api.DEFAULT_VPC_ID && provider == api.CLOUD_PROVIDER_ONECLOUD {
|
||||
var err error
|
||||
GuestnetworkManager.lockAllocMappedAddr(ctx)
|
||||
defer GuestnetworkManager.unlockAllocMappedAddr(ctx)
|
||||
gn.MappedIpAddr, err = GuestnetworkManager.allocMappedIpAddr(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var err error
|
||||
if ipBindMac := NetworkIpMacManager.GetMacFromIp(network.Id, gn.IpAddr); ipBindMac != "" {
|
||||
gn.MacAddr = ipBindMac
|
||||
@@ -416,6 +408,17 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
}
|
||||
}
|
||||
|
||||
if vpc.Id != api.DEFAULT_VPC_ID && provider == api.CLOUD_PROVIDER_ONECLOUD && len(gn.IpAddr) > 0 || len(gn.Ip6Addr) > 0 {
|
||||
var err error
|
||||
GuestnetworkManager.lockAllocMappedAddr(ctx)
|
||||
defer GuestnetworkManager.unlockAllocMappedAddr(ctx)
|
||||
gn.MappedIpAddr, err = GuestnetworkManager.allocMappedIpAddr(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GuestnetworkManager.allocMappedIpAddr")
|
||||
}
|
||||
gn.MappedIp6Addr = api.GenVpcMappedIP6(gn.MappedIpAddr)
|
||||
}
|
||||
|
||||
ifname, err = gn.checkOrAllocateIfname(network, ifname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -609,12 +612,22 @@ func (gn *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.Guestnet
|
||||
} else {
|
||||
if _, err := db.Update(gn, func() error {
|
||||
gn.MappedIpAddr = addr
|
||||
gn.MappedIp6Addr = api.GenVpcMappedIP6(addr)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Errorf("getJsonDescOneCloudVpc: row %d: db update mapped addr: %v", gn.RowId, err)
|
||||
gn.MappedIpAddr = ""
|
||||
gn.MappedIp6Addr = ""
|
||||
}
|
||||
}
|
||||
} else if gn.MappedIp6Addr == "" {
|
||||
if _, err := db.Update(gn, func() error {
|
||||
gn.MappedIp6Addr = api.GenVpcMappedIP6(gn.MappedIpAddr)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Errorf("getJsonDescOneCloudVpc for v6: row %d: db update mapped addr6: %v", gn.RowId, err)
|
||||
gn.MappedIp6Addr = ""
|
||||
}
|
||||
}
|
||||
|
||||
desc := gn.getJsonDesc()
|
||||
@@ -623,6 +636,7 @@ func (gn *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.Guestnet
|
||||
desc.Vpc.Id = vpc.Id
|
||||
desc.Vpc.Provider = api.VPC_PROVIDER_OVN
|
||||
desc.Vpc.MappedIpAddr = gn.MappedIpAddr
|
||||
desc.Vpc.MappedIp6Addr = gn.MappedIp6Addr
|
||||
|
||||
return desc
|
||||
}
|
||||
@@ -1364,3 +1378,70 @@ func (manager *SGuestnetworkManager) ListItemExportKeys(ctx context.Context,
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworkManager) InitializeData() error {
|
||||
err := manager.initOvnMappedIps()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "initOvnMappedIps")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworkManager) initOvnMappedIps() error {
|
||||
q := manager.Query()
|
||||
networksQ := NetworkManager.Query().SubQuery()
|
||||
wiresQ := WireManager.Query().SubQuery()
|
||||
vpcQ := VpcManager.Query().SubQuery()
|
||||
regionQ := CloudregionManager.Query().SubQuery()
|
||||
|
||||
q = q.Join(networksQ, sqlchemy.Equals(q.Field("network_id"), networksQ.Field("id")))
|
||||
q = q.Join(wiresQ, sqlchemy.Equals(networksQ.Field("wire_id"), wiresQ.Field("id")))
|
||||
q = q.Join(vpcQ, sqlchemy.Equals(wiresQ.Field("vpc_id"), vpcQ.Field("id")))
|
||||
q = q.Join(regionQ, sqlchemy.Equals(vpcQ.Field("cloudregion_id"), regionQ.Field("id")))
|
||||
|
||||
q = q.Filter(sqlchemy.Equals(regionQ.Field("provider"), api.CLOUD_PROVIDER_ONECLOUD))
|
||||
q = q.Filter(sqlchemy.NotEquals(vpcQ.Field("id"), api.DEFAULT_VPC_ID))
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.IsEmpty(q.Field("mapped_ip_addr")),
|
||||
sqlchemy.IsEmpty(q.Field("mapped_ip6_addr")),
|
||||
))
|
||||
|
||||
gns := make([]SGuestnetwork, 0)
|
||||
err := db.FetchModelObjects(manager, q, &gns)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
|
||||
for i := range gns {
|
||||
gn := &gns[i]
|
||||
var v4addr string
|
||||
if gn.MappedIpAddr == "" {
|
||||
addr, err := manager.allocMappedIpAddr(context.Background())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "allocMappedIpAddr")
|
||||
}
|
||||
v4addr = addr
|
||||
} else {
|
||||
v4addr = gn.MappedIpAddr
|
||||
}
|
||||
if _, err := db.Update(gn, func() error {
|
||||
gn.MappedIpAddr = v4addr
|
||||
gn.MappedIp6Addr = api.GenVpcMappedIP6(v4addr)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "db.Update")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (guest *SGuest) IsStrictIpv6() (bool, error) {
|
||||
q := GuestnetworkManager.Query().Equals("guest_id", guest.Id)
|
||||
q = q.IsNotEmpty("ip6_addr").IsNullOrEmpty("ip_addr").IsFalse("virtual")
|
||||
cnt, err := q.CountWithError()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "CountWithError")
|
||||
}
|
||||
return cnt > 0, nil
|
||||
}
|
||||
|
||||
@@ -3730,7 +3730,6 @@ func (self *SGuest) attach2NetworkOnce(
|
||||
teamWithMac = args.teamWithMac
|
||||
)
|
||||
network.updateDnsRecord(guestnic, true)
|
||||
network.updateGuestNetmap(guestnic)
|
||||
if pendingUsage != nil && len(teamWithMac) == 0 {
|
||||
cancelUsage := SRegionQuota{}
|
||||
if network.IsExitNetwork() {
|
||||
|
||||
@@ -196,6 +196,7 @@ func (self *SGuest) doPrepaidRecycleNoLock(ctx context.Context, userCred mcclien
|
||||
1,
|
||||
net.WireId,
|
||||
"",
|
||||
"",
|
||||
1000,
|
||||
nicType,
|
||||
i,
|
||||
@@ -205,7 +206,10 @@ func (self *SGuest) doPrepaidRecycleNoLock(ctx context.Context, userCred mcclien
|
||||
&ifname,
|
||||
&brname,
|
||||
false,
|
||||
false)
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("fail to addNetInterface %d: %s", i, err)
|
||||
fakeHost.RealDelete(ctx, userCred)
|
||||
@@ -546,7 +550,7 @@ func (self *SHost) BorrowIpAddrsFromGuest(ctx context.Context, userCred mcclient
|
||||
return fmt.Errorf(msg)
|
||||
}
|
||||
|
||||
err = self.EnableNetif(ctx, userCred, netif, "", guestnics[i].IpAddr, "", "", false, false)
|
||||
err = self.EnableNetif(ctx, userCred, netif, "", guestnics[i].IpAddr, guestnics[i].Ip6Addr, "", "", false, false, false, false)
|
||||
if err != nil {
|
||||
log.Errorf("fail to enable netif %s %s", guestnics[i].IpAddr, err)
|
||||
return err
|
||||
@@ -586,6 +590,7 @@ func (host *SHost) SetGuestCreateNetworkAndDiskParams(ctx context.Context, userC
|
||||
Network: hn.NetworkId,
|
||||
Mac: netifs[i].Mac,
|
||||
Address: hn.IpAddr,
|
||||
Address6: hn.Ip6Addr,
|
||||
Reserved: true,
|
||||
})
|
||||
netIdx += 1
|
||||
|
||||
@@ -62,6 +62,8 @@ type SHostnetwork struct {
|
||||
NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
|
||||
// IP地址
|
||||
IpAddr string `width:"16" charset:"ascii" list:"domain"`
|
||||
// IPv6地址
|
||||
Ip6Addr string `width:"64" charset:"ascii" list:"domain"`
|
||||
// MAC地址
|
||||
MacAddr string `width:"18" charset:"ascii" list:"domain"`
|
||||
// VLAN
|
||||
|
||||
+300
-76
@@ -209,6 +209,8 @@ type SHost struct {
|
||||
|
||||
// IPv4地址,作为私有云vpc访问外网时的网关
|
||||
OvnMappedIpAddr string `width:"16" charset:"ascii" nullable:"true" list:"user"`
|
||||
// IPv6地址,作为私有云vpc访问外网时的网关
|
||||
OvnMappedIp6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user"`
|
||||
|
||||
// UEFI详情
|
||||
UefiInfo jsonutils.JSONObject `nullable:"true" get:"domain" update:"domain" create:"domain_optional"`
|
||||
@@ -2148,8 +2150,13 @@ func (hh *SHost) DeleteBaremetalnetwork(ctx context.Context, userCred mcclient.T
|
||||
net := bn.GetNetwork()
|
||||
bn.Delete(ctx, userCred)
|
||||
db.OpsLog.LogDetachEvent(ctx, hh, net, userCred, nil)
|
||||
if reserve && net != nil && len(bn.IpAddr) > 0 && regutils.MatchIP4Addr(bn.IpAddr) {
|
||||
ReservedipManager.ReserveIP(ctx, userCred, net, bn.IpAddr, "Delete baremetalnetwork to reserve", api.AddressTypeIPv4)
|
||||
if reserve && net != nil {
|
||||
if len(bn.IpAddr) > 0 && regutils.MatchIP4Addr(bn.IpAddr) {
|
||||
ReservedipManager.ReserveIP(ctx, userCred, net, bn.IpAddr, "Delete baremetalnetwork to reserve", api.AddressTypeIPv4)
|
||||
}
|
||||
if len(bn.Ip6Addr) > 0 && regutils.MatchIP6Addr(bn.Ip6Addr) {
|
||||
ReservedipManager.ReserveIP(ctx, userCred, net, bn.Ip6Addr, "Delete baremetalnetwork to reserve", api.AddressTypeIPv6)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3675,11 +3682,14 @@ func fetchHostNics(hostIds []string) (map[string][]*types.SNic, error) {
|
||||
wires.Field("name").Label("wire"),
|
||||
wires.Field("bandwidth"),
|
||||
hn.Field("ip_addr"),
|
||||
hn.Field("ip6_addr"),
|
||||
networks.Field("guest_gateway").Label("gateway"),
|
||||
networks.Field("guest_gateway6").Label("gateway6"),
|
||||
networks.Field("guest_dns").Label("dns"),
|
||||
networks.Field("guest_domain").Label("domain"),
|
||||
networks.Field("guest_ntp").Label("ntp"),
|
||||
networks.Field("guest_ip_mask").Label("masklen"),
|
||||
networks.Field("guest_ip6_mask").Label("masklen6"),
|
||||
networks.Field("name").Label("net"),
|
||||
networks.Field("id").Label("net_id"),
|
||||
zones.Field("name").Label("zone"),
|
||||
@@ -4306,6 +4316,7 @@ func (hh *SHost) PostCreate(
|
||||
if hh.OvnVersion != "" && hh.OvnMappedIpAddr == "" {
|
||||
HostManager.lockAllocOvnMappedIpAddr(ctx)
|
||||
defer HostManager.unlockAllocOvnMappedIpAddr(ctx)
|
||||
|
||||
addr, err := HostManager.allocOvnMappedIpAddr(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("host %s(%s): alloc vpc mapped addr: %v",
|
||||
@@ -4313,6 +4324,7 @@ func (hh *SHost) PostCreate(
|
||||
}
|
||||
if _, err := db.Update(hh, func() error {
|
||||
hh.OvnMappedIpAddr = addr
|
||||
hh.OvnMappedIp6Addr = api.GenVpcMappedIP6(addr)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Errorf("host %s(%s): db update vpc mapped addr: %v",
|
||||
@@ -4722,6 +4734,7 @@ func (hh *SHost) PostUpdate(ctx context.Context, userCred mcclient.TokenCredenti
|
||||
if hh.OvnVersion != "" && hh.OvnMappedIpAddr == "" {
|
||||
HostManager.lockAllocOvnMappedIpAddr(ctx)
|
||||
defer HostManager.unlockAllocOvnMappedIpAddr(ctx)
|
||||
|
||||
addr, err := HostManager.allocOvnMappedIpAddr(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("host %s(%s): alloc vpc mapped addr: %v",
|
||||
@@ -4730,6 +4743,7 @@ func (hh *SHost) PostUpdate(ctx context.Context, userCred mcclient.TokenCredenti
|
||||
}
|
||||
if _, err := db.Update(hh, func() error {
|
||||
hh.OvnMappedIpAddr = addr
|
||||
hh.OvnMappedIp6Addr = api.GenVpcMappedIP6(addr)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Errorf("host %s(%s): db update vpc mapped addr: %v",
|
||||
@@ -5590,6 +5604,10 @@ func (h *SHost) PerformAddNetif(
|
||||
if len(ipAddr) > 0 && !regutils.MatchIP4Addr(ipAddr) {
|
||||
return nil, errors.Wrapf(httperrors.ErrInputParameter, "invalid ip_addr %s", ipAddr)
|
||||
}
|
||||
ip6Addr := input.Ip6Addr
|
||||
if len(ip6Addr) > 0 && !regutils.MatchIP6Addr(ip6Addr) {
|
||||
return nil, errors.Wrapf(httperrors.ErrInputParameter, "invalid ip6_addr %s", ip6Addr)
|
||||
}
|
||||
rate := input.Rate
|
||||
nicType := input.NicType
|
||||
index := input.Index
|
||||
@@ -5600,6 +5618,8 @@ func (h *SHost) PerformAddNetif(
|
||||
bridge := input.Bridge
|
||||
reserve := (input.Reserve != nil && *input.Reserve)
|
||||
requireDesignatedIp := (input.RequireDesignatedIp != nil && *input.RequireDesignatedIp)
|
||||
requireIpv6 := (input.RequireIpv6 != nil && *input.RequireIpv6)
|
||||
strictIpv6 := (input.StrictIpv6 != nil && *input.StrictIpv6)
|
||||
|
||||
isLinkUp := tristate.None
|
||||
if linkUp != "" {
|
||||
@@ -5610,16 +5630,16 @@ func (h *SHost) PerformAddNetif(
|
||||
}
|
||||
}
|
||||
|
||||
err = h.addNetif(ctx, userCred, mac, vlan, wire, ipAddr, int(rate), nicType, index, isLinkUp,
|
||||
int16(mtu), reset, netIf, bridge, reserve, requireDesignatedIp)
|
||||
err = h.addNetif(ctx, userCred, mac, vlan, wire, ipAddr, ip6Addr, int(rate), nicType, index, isLinkUp,
|
||||
int16(mtu), reset, netIf, bridge, reserve, requireDesignatedIp, requireIpv6, strictIpv6)
|
||||
return nil, errors.Wrap(err, "addNetif")
|
||||
}
|
||||
|
||||
func (h *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
mac string, vlanId int, wire string, ipAddr string,
|
||||
mac string, vlanId int, wire string, ipAddr string, ip6Addr string,
|
||||
rate int, nicType compute.TNicType, index int, linkUp tristate.TriState, mtu int16,
|
||||
reset bool, strInterface *string, strBridge *string,
|
||||
reserve bool, requireDesignatedIp bool,
|
||||
reserve bool, requireDesignatedIp bool, requireIpv6 bool, strictIpv6 bool,
|
||||
) error {
|
||||
var sw *SWire
|
||||
if len(wire) > 0 {
|
||||
@@ -5632,32 +5652,78 @@ func (h *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
}
|
||||
}
|
||||
sw = iWire.(*SWire)
|
||||
if len(ipAddr) > 0 {
|
||||
iIpAddr, err := netutils.NewIPV4Addr(ipAddr)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError("invalid ipaddr %s", ipAddr)
|
||||
if len(ipAddr) > 0 || len(ip6Addr) > 0 {
|
||||
var v4addr *netutils.IPV4Addr
|
||||
var v6addr *netutils.IPV6Addr
|
||||
if len(ipAddr) > 0 {
|
||||
iIpAddr, err := netutils.NewIPV4Addr(ipAddr)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError("invalid ipaddr %s", ipAddr)
|
||||
}
|
||||
v4addr = &iIpAddr
|
||||
}
|
||||
findAddr := false
|
||||
if len(ip6Addr) > 0 {
|
||||
iIp6Addr, err := netutils.NewIPV6Addr(ip6Addr)
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError("invalid ip6addr %s", ip6Addr)
|
||||
}
|
||||
v6addr = &iIp6Addr
|
||||
}
|
||||
|
||||
var v4net, v6net *SNetwork
|
||||
swNets, err := sw.getNetworks(ctx, userCred, userCred, NetworkManager.AllowScope(userCred))
|
||||
if err != nil {
|
||||
return httperrors.NewInputParameterError("no networks on wire %s", wire)
|
||||
}
|
||||
for i := range swNets {
|
||||
if swNets[i].IsAddressInRange(iIpAddr) {
|
||||
findAddr = true
|
||||
if v4net == nil && v4addr != nil && swNets[i].IsAddressInRange(*v4addr) {
|
||||
v4net = &swNets[i]
|
||||
}
|
||||
if v6net == nil && v6addr != nil && swNets[i].IsAddress6InRange(*v6addr) {
|
||||
v6net = &swNets[i]
|
||||
}
|
||||
if v4net != nil && v6net != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !findAddr {
|
||||
return httperrors.NewBadRequestError("IP %s not attach to wire %s", ipAddr, wire)
|
||||
if v4net == nil && v6net == nil {
|
||||
var addrs []string
|
||||
if len(ipAddr) > 0 {
|
||||
addrs = append(addrs, ipAddr)
|
||||
}
|
||||
if len(ip6Addr) > 0 {
|
||||
addrs = append(addrs, ip6Addr)
|
||||
}
|
||||
return httperrors.NewBadRequestError("IP %s not attach to wire %s", strings.Join(addrs, ","), wire)
|
||||
}
|
||||
if v4net != nil && v6net != nil && v4net.Id != v6net.Id {
|
||||
return httperrors.NewConflictError("IPv4 %s and IPv6 %s must be on the same network", ipAddr, ip6Addr)
|
||||
}
|
||||
}
|
||||
} else if len(ipAddr) > 0 && len(wire) == 0 {
|
||||
ipWire, err := WireManager.GetOnPremiseWireOfIp(ipAddr)
|
||||
if err != nil {
|
||||
return httperrors.NewBadRequestError("IP %s not attach to any wire", ipAddr)
|
||||
} else {
|
||||
var v4wire, v6wire *SWire
|
||||
if len(ipAddr) > 0 {
|
||||
ipWire, err := WireManager.GetOnPremiseWireOfIp(ipAddr)
|
||||
if err != nil {
|
||||
return httperrors.NewBadRequestError("IP %s not attach to any wire", ipAddr)
|
||||
}
|
||||
v4wire = ipWire
|
||||
}
|
||||
if len(ip6Addr) > 0 {
|
||||
ipWire, err := WireManager.GetOnPremiseWireOfIp6(ip6Addr)
|
||||
if err != nil {
|
||||
return httperrors.NewBadRequestError("IPv6 %s not attach to any wire", ip6Addr)
|
||||
}
|
||||
v6wire = ipWire
|
||||
}
|
||||
if v4wire != nil && v6wire != nil && v4wire.Id != v6wire.Id {
|
||||
return httperrors.NewConflictError("IPv4 %s and IPv6 %s must be on the same wire", ipAddr, ip6Addr)
|
||||
}
|
||||
if v4wire != nil {
|
||||
sw = v4wire
|
||||
} else if v6wire != nil {
|
||||
sw = v6wire
|
||||
}
|
||||
sw = ipWire
|
||||
}
|
||||
netif, err := NetInterfaceManager.FetchByMacVlan(mac, vlanId)
|
||||
if err != nil {
|
||||
@@ -5762,8 +5828,8 @@ func (h *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(ipAddr) > 0 {
|
||||
err = h.EnableNetif(ctx, userCred, netif, "", ipAddr, "", "", reserve, requireDesignatedIp)
|
||||
if len(ipAddr) > 0 || len(ip6Addr) > 0 {
|
||||
err = h.EnableNetif(ctx, userCred, netif, "", ipAddr, ip6Addr, "", "", reserve, requireDesignatedIp, requireIpv6, strictIpv6)
|
||||
if err != nil {
|
||||
return httperrors.NewBadRequestError("%v", err)
|
||||
}
|
||||
@@ -5795,8 +5861,10 @@ func (h *SHost) PerformEnableNetif(
|
||||
|
||||
reserve := (input.Reserve != nil && *input.Reserve)
|
||||
requireDesignatedIp := (input.RequireDesignatedIp != nil && *input.RequireDesignatedIp)
|
||||
requireIpv6 := (input.RequireIpv6 != nil && *input.RequireIpv6)
|
||||
strictIpv6 := (input.StrictIpv6 != nil && *input.StrictIpv6)
|
||||
|
||||
err = h.EnableNetif(ctx, userCred, netif, input.NetworkId, input.IpAddr, input.AllocDir, input.NetType, reserve, requireDesignatedIp)
|
||||
err = h.EnableNetif(ctx, userCred, netif, input.NetworkId, input.IpAddr, input.Ip6Addr, input.AllocDir, input.NetType, reserve, requireDesignatedIp, requireIpv6, strictIpv6)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError("%v", err)
|
||||
}
|
||||
@@ -5804,27 +5872,64 @@ func (h *SHost) PerformEnableNetif(
|
||||
}
|
||||
|
||||
func (h *SHost) EnableNetif(ctx context.Context, userCred mcclient.TokenCredential, netif *SNetInterface,
|
||||
network, ipAddr, allocDir string, netType api.TNetworkType, reserve, requireDesignatedIp bool) error {
|
||||
bn := netif.GetHostNetwork()
|
||||
if bn != nil {
|
||||
log.Debugf("Netif has been attach2network? %s", jsonutils.Marshal(bn))
|
||||
return nil
|
||||
}
|
||||
var net *SNetwork
|
||||
network, ipAddr, ip6Addr, allocDir string, netType api.TNetworkType, reserve, requireDesignatedIp bool,
|
||||
requireIpv6 bool, strictIpv6 bool) error {
|
||||
// bn := netif.GetHostNetwork()
|
||||
// if bn != nil {
|
||||
// log.Debugf("Netif has been attach2network? %s", jsonutils.Marshal(bn))
|
||||
// return nil
|
||||
// }
|
||||
var v4net, v6net *SNetwork
|
||||
var err error
|
||||
if len(ipAddr) > 0 {
|
||||
net, err = netif.GetCandidateNetworkForIp(ctx, userCred, userCred, NetworkManager.AllowScope(userCred), ipAddr)
|
||||
if len(ipAddr) > 0 && !strictIpv6 {
|
||||
net, err := netif.GetCandidateNetworkForIp(ctx, userCred, userCred, NetworkManager.AllowScope(userCred), ipAddr)
|
||||
if net != nil {
|
||||
log.Infof("find network %s for ip %s", net.GetName(), ipAddr)
|
||||
log.Infof("find network %s for ip4 %s", net.GetName(), ipAddr)
|
||||
v4net = net
|
||||
} else if requireDesignatedIp {
|
||||
log.Errorf("Cannot allocate IP %s, not reachable", ipAddr)
|
||||
return fmt.Errorf("Cannot allocate IP %s, not reachable", ipAddr)
|
||||
log.Errorf("Cannot allocate IP %s, not reachable: %s", ipAddr, err)
|
||||
return fmt.Errorf("Cannot allocate IP %s, not reachable: %s", ipAddr, err)
|
||||
} else {
|
||||
log.Infof("not found network with scope: %s, ip_addr: %s", NetworkManager.AllowScope(userCred), ipAddr)
|
||||
log.Infof("not found network with scope: %s, ip_addr: %s, err: %s", NetworkManager.AllowScope(userCred), ipAddr, err)
|
||||
// the ipaddr is not usable, should be reset to empty
|
||||
ipAddr = ""
|
||||
}
|
||||
}
|
||||
if len(ip6Addr) > 0 {
|
||||
if v4net != nil {
|
||||
ip6, err := netutils.NewIPV6Addr(ip6Addr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "netutils.NewIPV6Addr: %s", ip6Addr)
|
||||
}
|
||||
if v4net.IsAddress6InRange(ip6) {
|
||||
v6net = v4net
|
||||
}
|
||||
} else {
|
||||
net, err := netif.GetCandidateNetworkForIp6(ctx, userCred, userCred, NetworkManager.AllowScope(userCred), ip6Addr)
|
||||
if net != nil {
|
||||
log.Infof("find network %s for ip %s", net.GetName(), ip6Addr)
|
||||
v6net = net
|
||||
} else if requireIpv6 {
|
||||
log.Errorf("Cannot allocate IPv6 %s, not reachable: %s", ip6Addr, err)
|
||||
return fmt.Errorf("Cannot allocate IPv6 %s, not reachable: %s", ip6Addr, err)
|
||||
} else {
|
||||
log.Infof("not found network with scope: %s, ip6_addr: %s, err: %s", NetworkManager.AllowScope(userCred), ip6Addr, err)
|
||||
// the ipaddr is not usable, should be reset to empty
|
||||
ip6Addr = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
var net *SNetwork
|
||||
if v4net != nil && v6net != nil {
|
||||
if v4net.Id != v6net.Id {
|
||||
return errors.Wrap(httperrors.ErrConflict, "v4net and v6net must be on the same network")
|
||||
}
|
||||
net = v4net
|
||||
} else if v6net != nil {
|
||||
net = v6net
|
||||
} else if v4net != nil {
|
||||
net = v4net
|
||||
}
|
||||
wire := netif.GetWire()
|
||||
if wire == nil {
|
||||
return fmt.Errorf("No wire attached")
|
||||
@@ -5879,20 +5984,28 @@ func (h *SHost) EnableNetif(ctx context.Context, userCred mcclient.TokenCredenti
|
||||
allocDir: allocDir,
|
||||
reserved: reserve,
|
||||
requireDesignatedIp: requireDesignatedIp,
|
||||
|
||||
ip6Addr: ip6Addr,
|
||||
requireIpv6: requireIpv6,
|
||||
strictIpv6: strictIpv6,
|
||||
}
|
||||
|
||||
bn, err = h.Attach2Network(ctx, userCred, attachOpt)
|
||||
bn, err := h.attach2Network(ctx, userCred, attachOpt)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "hh.Attach2Network")
|
||||
}
|
||||
bnIP := bn.IpAddr
|
||||
if len(bnIP) == 0 {
|
||||
bnIP = bn.Ip6Addr
|
||||
}
|
||||
switch netif.NicType {
|
||||
case api.NIC_TYPE_IPMI:
|
||||
err = h.setIpmiIp(userCred, bn.IpAddr)
|
||||
err = h.setIpmiIp(userCred, bnIP)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "setIpmiIp")
|
||||
}
|
||||
case api.NIC_TYPE_ADMIN:
|
||||
err = h.setAccessIp(userCred, bn.IpAddr)
|
||||
err = h.setAccessIp(userCred, bnIP)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "setAccessIp")
|
||||
}
|
||||
@@ -5928,20 +6041,21 @@ func (hh *SHost) PerformDisableNetif(
|
||||
*/
|
||||
func (hh *SHost) DisableNetif(ctx context.Context, userCred mcclient.TokenCredential, netif *SNetInterface, reserve bool) error {
|
||||
bn := netif.GetHostNetwork()
|
||||
var ipAddr string
|
||||
var ipAddr, ip6Addr string
|
||||
if bn != nil {
|
||||
ipAddr = bn.IpAddr
|
||||
ip6Addr = bn.Ip6Addr
|
||||
hh.UpdateDnsRecord(netif, false)
|
||||
hh.DeleteBaremetalnetwork(ctx, userCred, bn, reserve)
|
||||
}
|
||||
var err error
|
||||
switch netif.NicType {
|
||||
case api.NIC_TYPE_IPMI:
|
||||
if ipAddr == hh.IpmiIp {
|
||||
if ipAddr == hh.IpmiIp || ip6Addr == hh.IpmiIp {
|
||||
err = hh.setIpmiIp(userCred, "")
|
||||
}
|
||||
case api.NIC_TYPE_ADMIN:
|
||||
if ipAddr == hh.AccessIp {
|
||||
if ipAddr == hh.AccessIp || ip6Addr == hh.AccessIp {
|
||||
err = hh.setAccessIp(userCred, "")
|
||||
}
|
||||
}
|
||||
@@ -5955,16 +6069,21 @@ type hostAttachNetworkOption struct {
|
||||
allocDir string
|
||||
reserved bool
|
||||
requireDesignatedIp bool
|
||||
|
||||
ip6Addr string
|
||||
requireIpv6 bool
|
||||
strictIpv6 bool
|
||||
}
|
||||
|
||||
func (hh *SHost) IsIpAddrWithinConvertedGuest(ctx context.Context, userCred mcclient.TokenCredential, ipAddr string, netif *SNetInterface) error {
|
||||
func (hh *SHost) IsIpAddrWithinConvertedGuest(ctx context.Context, userCred mcclient.TokenCredential, ipAddr, ip6Addr string, netif *SNetInterface) error {
|
||||
if !hh.IsBaremetal {
|
||||
return httperrors.NewNotAcceptableError("Not a baremetal")
|
||||
}
|
||||
|
||||
if hh.HostType == api.HOST_TYPE_KVM {
|
||||
return httperrors.NewNotAcceptableError("Not being convert to hypervisor")
|
||||
}
|
||||
// ?
|
||||
// if hh.HostType == api.HOST_TYPE_KVM {
|
||||
// return httperrors.NewNotAcceptableError("Not being convert to hypervisor")
|
||||
// }
|
||||
|
||||
bmServer := hh.GetBaremetalServer()
|
||||
if bmServer == nil {
|
||||
@@ -5987,59 +6106,118 @@ func (hh *SHost) IsIpAddrWithinConvertedGuest(ctx context.Context, userCred mccl
|
||||
return httperrors.NewNotFoundError("Not found guest nic by mac %s", netif.Mac)
|
||||
}
|
||||
|
||||
if findNic.IpAddr != ipAddr {
|
||||
if len(ipAddr) > 0 && findNic.IpAddr != ipAddr {
|
||||
return httperrors.NewNotAcceptableError("Guest nic ip addr %s not equal %s", findNic.IpAddr, ipAddr)
|
||||
}
|
||||
if len(ip6Addr) > 0 && findNic.Ip6Addr != ip6Addr {
|
||||
return httperrors.NewNotAcceptableError("Guest nic ip addr6 %s not equal %s", findNic.Ip6Addr, ip6Addr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hh *SHost) Attach2Network(
|
||||
func (hh *SHost) attach2Network(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
opt *hostAttachNetworkOption,
|
||||
) (*SHostnetwork, error) {
|
||||
log.Infof("host attach2Network: %s", jsonutils.Marshal(opt))
|
||||
|
||||
netif := opt.netif
|
||||
net := opt.net
|
||||
ipAddr := opt.ipAddr
|
||||
ip6Addr := opt.ip6Addr
|
||||
allocDir := opt.allocDir
|
||||
reserved := opt.reserved
|
||||
requireDesignatedIp := opt.requireDesignatedIp
|
||||
|
||||
bn := opt.netif.GetHostNetwork()
|
||||
|
||||
lockman.LockObject(ctx, net)
|
||||
defer lockman.ReleaseObject(ctx, net)
|
||||
|
||||
usedAddrs := net.GetUsedAddresses(ctx)
|
||||
if ipAddr != "" {
|
||||
// converted baremetal can resuse related guest network ip
|
||||
if err := hh.IsIpAddrWithinConvertedGuest(ctx, userCred, ipAddr, netif); err == nil {
|
||||
// force remove used server addr for reuse
|
||||
delete(usedAddrs, ipAddr)
|
||||
} else {
|
||||
log.Warningf("check IsIpAddrWithinConvertedGuest: %v", err)
|
||||
var freeIp4, freeIp6 string
|
||||
if (!opt.strictIpv6 || len(ipAddr) > 0) && (bn == nil || bn.IpAddr != ipAddr) {
|
||||
// allocate ipv4 address
|
||||
usedAddrs := net.GetUsedAddresses(ctx)
|
||||
if ipAddr != "" {
|
||||
// converted baremetal can resuse related guest network ip
|
||||
if err := hh.IsIpAddrWithinConvertedGuest(ctx, userCred, ipAddr, "", netif); err == nil {
|
||||
// force remove used server addr for reuse
|
||||
delete(usedAddrs, ipAddr)
|
||||
} else {
|
||||
log.Warningf("check IsIpAddrWithinConvertedGuest: %v", err)
|
||||
}
|
||||
}
|
||||
freeIp, err := net.GetFreeIP(ctx, userCred, usedAddrs, nil, ipAddr, api.IPAllocationDirection(allocDir), reserved, api.AddressTypeIPv4)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "net.GetFreeIPv4")
|
||||
}
|
||||
if len(ipAddr) > 0 && ipAddr != freeIp && requireDesignatedIp {
|
||||
return nil, fmt.Errorf("IPv4 address %s is occupied, get %s instead", ipAddr, freeIp)
|
||||
}
|
||||
freeIp4 = freeIp
|
||||
}
|
||||
if (opt.requireIpv6 || len(ip6Addr) > 0) && (bn == nil || bn.Ip6Addr != ip6Addr) {
|
||||
usedAddrs6 := net.GetUsedAddresses6(ctx)
|
||||
if ip6Addr != "" {
|
||||
// converted baremetal can resuse related guest network ip
|
||||
if err := hh.IsIpAddrWithinConvertedGuest(ctx, userCred, "", ip6Addr, netif); err == nil {
|
||||
// force remove used server addr for reuse
|
||||
delete(usedAddrs6, ip6Addr)
|
||||
} else {
|
||||
log.Warningf("check IsIpAddrWithinConvertedGuest: %v", err)
|
||||
}
|
||||
}
|
||||
freeIp, err := net.GetFreeIP(ctx, userCred, usedAddrs6, nil, ip6Addr, api.IPAllocationDirection(allocDir), reserved, api.AddressTypeIPv6)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "net.GetFreeIPv6")
|
||||
}
|
||||
if len(ip6Addr) > 0 && ip6Addr != freeIp && requireDesignatedIp {
|
||||
return nil, fmt.Errorf("IPv6 address %s is occupied, get %s instead", ip6Addr, freeIp)
|
||||
}
|
||||
freeIp6 = freeIp
|
||||
}
|
||||
|
||||
freeIp, err := net.GetFreeIP(ctx, userCred, usedAddrs, nil, ipAddr, api.IPAllocationDirection(allocDir), reserved, api.AddressTypeIPv4)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "net.GetFreeIP")
|
||||
if bn == nil {
|
||||
bn = &SHostnetwork{}
|
||||
bn.SetModelManager(HostnetworkManager, bn)
|
||||
bn.BaremetalId = hh.Id
|
||||
bn.NetworkId = net.Id
|
||||
bn.MacAddr = netif.Mac
|
||||
bn.IpAddr = freeIp4
|
||||
bn.Ip6Addr = freeIp6
|
||||
err := HostnetworkManager.TableSpec().Insert(ctx, bn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "HostnetworkManager.TableSpec().Insert")
|
||||
}
|
||||
} else if (freeIp4 != "" && freeIp4 != bn.IpAddr) || (freeIp6 != "" && freeIp6 != bn.Ip6Addr) {
|
||||
_, err := db.Update(bn, func() error {
|
||||
if freeIp4 != "" {
|
||||
bn.IpAddr = freeIp4
|
||||
}
|
||||
if freeIp6 != "" {
|
||||
bn.Ip6Addr = freeIp6
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "HostnetworkManager.TableSpec().Insert")
|
||||
}
|
||||
} else {
|
||||
return bn, nil
|
||||
}
|
||||
if len(ipAddr) > 0 && ipAddr != freeIp && requireDesignatedIp {
|
||||
return nil, fmt.Errorf("IP address %s is occupied, get %s instead", ipAddr, freeIp)
|
||||
|
||||
var addrs []string
|
||||
if len(freeIp4) > 0 {
|
||||
addrs = append(addrs, freeIp4)
|
||||
}
|
||||
bn := &SHostnetwork{}
|
||||
bn.BaremetalId = hh.Id
|
||||
bn.SetModelManager(HostnetworkManager, bn)
|
||||
bn.NetworkId = net.Id
|
||||
bn.IpAddr = freeIp
|
||||
bn.MacAddr = netif.Mac
|
||||
err = HostnetworkManager.TableSpec().Insert(ctx, bn)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "HostnetworkManager.TableSpec().Insert")
|
||||
if len(freeIp6) > 0 {
|
||||
addrs = append(addrs, freeIp6)
|
||||
}
|
||||
db.OpsLog.LogAttachEvent(ctx, hh, net, userCred, jsonutils.NewString(freeIp))
|
||||
db.OpsLog.LogAttachEvent(ctx, hh, net, userCred, jsonutils.NewString(strings.Join(addrs, ",")))
|
||||
hh.UpdateDnsRecord(netif, true)
|
||||
net.UpdateBaremetalNetmap(bn, hh.GetNetifName(netif))
|
||||
// net.UpdateBaremetalNetmap(bn, hh.GetNetifName(netif))
|
||||
return bn, nil
|
||||
}
|
||||
|
||||
@@ -6587,7 +6765,7 @@ func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.T
|
||||
netif := host.GetNetInterface(enables[i].GetMac(), enables[i].GetVlanId())
|
||||
// always true reserved address pool
|
||||
log.Debugf("enable netif %s", enables[i].GetMac())
|
||||
err = host.EnableNetif(ctx, userCred, netif, "", enables[i].GetIpAddr(), "", "", true, true)
|
||||
err = host.EnableNetif(ctx, userCred, netif, "", enables[i].GetIpAddr(), "", "", "", true, true, false, false)
|
||||
if err != nil {
|
||||
result.AddError(err)
|
||||
} else {
|
||||
@@ -6618,9 +6796,9 @@ func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.T
|
||||
wireId = wire.Id
|
||||
}
|
||||
}
|
||||
err = host.addNetif(ctx, userCred, extNic.GetMac(), extNic.GetVlanId(), wireId, extNic.GetIpAddr(), 0,
|
||||
err = host.addNetif(ctx, userCred, extNic.GetMac(), extNic.GetVlanId(), wireId, extNic.GetIpAddr(), "", 0,
|
||||
compute.TNicType(extNic.GetNicType()), int(extNic.GetIndex()),
|
||||
extNic.IsLinkUp(), int16(extNic.GetMtu()), false, strNetIf, strBridge, true, true)
|
||||
extNic.IsLinkUp(), int16(extNic.GetMtu()), false, strNetIf, strBridge, true, true, false, false)
|
||||
if err != nil {
|
||||
result.AddError(err)
|
||||
} else {
|
||||
@@ -7499,8 +7677,54 @@ func (manager *SHostManager) initHostname() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SHostManager) initOvnMappedIp6Addr() error {
|
||||
hosts := []SHost{}
|
||||
q := manager.Query().IsNotEmpty("ovn_version")
|
||||
q = q.Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.IsNullOrEmpty(q.Field("ovn_mapped_ip6_addr")),
|
||||
sqlchemy.IsNullOrEmpty(q.Field("ovn_mapped_ip_addr")),
|
||||
),
|
||||
)
|
||||
err := db.FetchModelObjects(manager, q, &hosts)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
for i := range hosts {
|
||||
hh := &hosts[i]
|
||||
var v4addr string
|
||||
if hh.OvnMappedIp6Addr == "" {
|
||||
addr, err := HostManager.allocOvnMappedIpAddr(context.Background())
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "host %s(%s): alloc vpc mapped addr", hh.Name, hh.Id)
|
||||
}
|
||||
v4addr = addr
|
||||
} else {
|
||||
v4addr = hh.OvnMappedIpAddr
|
||||
}
|
||||
|
||||
if _, err := db.Update(hh, func() error {
|
||||
hh.OvnMappedIpAddr = v4addr
|
||||
hh.OvnMappedIp6Addr = api.GenVpcMappedIP6(v4addr)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return errors.Wrapf(err, "host %s(%s): db update vpc mapped addr", hh.Name, hh.Id)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SHostManager) InitializeData() error {
|
||||
return manager.initHostname()
|
||||
var err error
|
||||
err = manager.initHostname()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "initHostname")
|
||||
}
|
||||
err = manager.initOvnMappedIp6Addr()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "initOvnMappedIp6Addr")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hh *SHost) PerformProbeIsolatedDevices(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -50,6 +50,7 @@ func InitDB() error {
|
||||
NetworkAddressManager,
|
||||
NetworkIpMacManager,
|
||||
GuestManager,
|
||||
GuestnetworkManager,
|
||||
HostManager,
|
||||
LoadbalancerCertificateManager,
|
||||
LoadbalancerAclManager,
|
||||
|
||||
@@ -169,10 +169,13 @@ func (netIf *SNetInterface) hostNetworkToJson(bn *SHostnetwork) *jsonutils.JSOND
|
||||
}
|
||||
}*/
|
||||
|
||||
func (netIf *SNetInterface) networkToNic(ipAddr string, network *SNetwork, nic *types.SNic) *types.SNic {
|
||||
func (netIf *SNetInterface) networkToNic(ipAddr, ip6Addr string, network *SNetwork, nic *types.SNic) *types.SNic {
|
||||
if len(ipAddr) > 0 {
|
||||
nic.IpAddr = ipAddr
|
||||
}
|
||||
if len(ip6Addr) > 0 {
|
||||
nic.Ip6Addr = ip6Addr
|
||||
}
|
||||
|
||||
if network != nil {
|
||||
if len(network.GuestGateway) > 0 && regutils.MatchIP4Addr(network.GuestGateway) {
|
||||
@@ -190,6 +193,11 @@ func (netIf *SNetInterface) networkToNic(ipAddr string, network *SNetwork, nic *
|
||||
nic.Masklen = network.GuestIpMask
|
||||
nic.Net = network.Name
|
||||
nic.NetId = network.Id
|
||||
|
||||
nic.Masklen6 = network.GuestIp6Mask
|
||||
if len(network.GuestGateway6) > 0 && regutils.MatchIP6Addr(network.GuestGateway6) {
|
||||
nic.Gateway6 = network.GuestGateway6
|
||||
}
|
||||
}
|
||||
|
||||
return nic
|
||||
@@ -256,7 +264,7 @@ func (netif *SNetInterface) getBaremetalJsonDesc() *types.SNic {
|
||||
}
|
||||
bn := netif.GetHostNetwork()
|
||||
if bn != nil {
|
||||
nic = netif.networkToNic(bn.IpAddr, bn.GetNetwork(), nic)
|
||||
nic = netif.networkToNic(bn.IpAddr, bn.Ip6Addr, bn.GetNetwork(), nic)
|
||||
}
|
||||
return nic
|
||||
}
|
||||
@@ -290,6 +298,15 @@ func (netIf *SNetInterface) GetCandidateNetworkForIp(ctx context.Context, userCr
|
||||
return wire.GetCandidateNetworkForIp(ctx, userCred, ownerId, scope, ipAddr)
|
||||
}
|
||||
|
||||
func (netIf *SNetInterface) GetCandidateNetworkForIp6(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, ip6Addr string) (*SNetwork, error) {
|
||||
wire := netIf.GetWire()
|
||||
if wire == nil {
|
||||
return nil, nil
|
||||
}
|
||||
log.Infof("ip6Addr: %s, netiName: %s, wire: %s", ip6Addr, netIf.GetName(), wire.GetName())
|
||||
return wire.GetCandidateNetworkForIp6(ctx, userCred, ownerId, scope, ip6Addr)
|
||||
}
|
||||
|
||||
func (netif *SNetInterface) IsUsableServernic() bool {
|
||||
if netif.NicType == api.NIC_TYPE_IPMI {
|
||||
return false
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -122,9 +121,9 @@ type SNetwork struct {
|
||||
// IPv6网关
|
||||
GuestGateway6 string `width:"64" charset:"ascii" nullable:"true" list:"user" update:"user" create:"optional"`
|
||||
// IPv6域名服务器
|
||||
GuestDns6 string `width:"64" charset:"ascii" nullable:"true"`
|
||||
// GuestDns6 string `width:"64" charset:"ascii" nullable:"true"`
|
||||
|
||||
GuestDomain6 string `width:"128" charset:"ascii" nullable:"true"`
|
||||
// GuestDomain6 string `width:"128" charset:"ascii" nullable:"true"`
|
||||
|
||||
VlanId int `nullable:"false" default:"1" list:"user" update:"user" create:"optional"`
|
||||
|
||||
@@ -582,19 +581,6 @@ func (snet *SNetwork) _updateDnsRecord(name string, ipAddr string, isAdd bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (snet *SNetwork) updateGuestNetmap(nic *SGuestnetwork) {
|
||||
// TODO
|
||||
|
||||
}
|
||||
|
||||
func (snet *SNetwork) UpdateBaremetalNetmap(nic *SHostnetwork, name string) {
|
||||
snet.UpdateNetmap(nic.IpAddr, auth.AdminCredential().GetTenantId(), name)
|
||||
}
|
||||
|
||||
func (snet *SNetwork) UpdateNetmap(ip, project, name string) {
|
||||
// TODO ??
|
||||
}
|
||||
|
||||
type DNSUpdateKeySecret struct {
|
||||
Key string
|
||||
Secret string
|
||||
@@ -951,6 +937,23 @@ func (manager *SNetworkManager) GetOnPremiseNetworkOfIP(ipAddr string, serverTyp
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) GetOnPremiseNetworkOfIP6(ip6Addr string, serverType string, isPublic tristate.TriState) (*SNetwork, error) {
|
||||
address, err := netutils.NewIPV6Addr(ip6Addr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewIPV6Addr")
|
||||
}
|
||||
nets, err := manager.fetchAllOnpremiseNetworks(serverType, isPublic)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetchAllOnpremiseNetworks")
|
||||
}
|
||||
for _, n := range nets {
|
||||
if n.IsAddress6InRange(address) {
|
||||
return &n, nil
|
||||
}
|
||||
}
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) allNetworksQ(providers []string, brands []string, cloudEnv string, rangeObjs []db.IStandaloneModel) *sqlchemy.SQuery {
|
||||
networks := manager.Query().SubQuery()
|
||||
wires := WireManager.Query().SubQuery()
|
||||
@@ -2579,7 +2582,7 @@ func (snet *SNetwork) isOneCloudVpcNetwork() bool {
|
||||
return IsOneCloudVpcResource(snet)
|
||||
}
|
||||
|
||||
func parseIpToIntArray(ip string) ([]int, error) {
|
||||
/*func parseIpToIntArray(ip string) ([]int, error) {
|
||||
ipSp := strings.Split(strings.Trim(ip, "."), ".")
|
||||
if len(ipSp) > 4 {
|
||||
return nil, httperrors.NewInputParameterError("Parse Ip Failed")
|
||||
@@ -2596,7 +2599,7 @@ func parseIpToIntArray(ip string) ([]int, error) {
|
||||
ipIa = append(ipIa, val)
|
||||
}
|
||||
return ipIa, nil
|
||||
}
|
||||
}*/
|
||||
|
||||
// IP子网列表
|
||||
func (manager *SNetworkManager) ListItemFilter(
|
||||
|
||||
@@ -66,8 +66,20 @@ func (manager *SHostnetworkManager) handleNetworkIdChange(ctx context.Context, a
|
||||
return err
|
||||
}
|
||||
for _, hn := range hns {
|
||||
addr, _ := netutils.NewIPV4Addr(hn.IpAddr)
|
||||
if args.newNet.IsAddressInRange(addr) {
|
||||
inNet := false
|
||||
if len(hn.IpAddr) > 0 {
|
||||
addr, _ := netutils.NewIPV4Addr(hn.IpAddr)
|
||||
if args.newNet.IsAddressInRange(addr) {
|
||||
inNet = true
|
||||
}
|
||||
}
|
||||
if len(hn.Ip6Addr) > 0 {
|
||||
addr, _ := netutils.NewIPV6Addr(hn.Ip6Addr)
|
||||
if args.newNet.IsAddress6InRange(addr) {
|
||||
inNet = true
|
||||
}
|
||||
}
|
||||
if inNet {
|
||||
_, err = db.Update(&hn, func() error {
|
||||
hn.NetworkId = args.newNet.Id
|
||||
return nil
|
||||
|
||||
@@ -1982,6 +1982,7 @@ func (svpc *SVpc) GetDetailsTopology(ctx context.Context, userCred mcclient.Toke
|
||||
for j := range hns {
|
||||
host.Networks = append(host.Networks, api.HostnetworkTopologyOutput{
|
||||
IpAddr: hns[j].IpAddr,
|
||||
Ip6Addr: hns[j].Ip6Addr,
|
||||
MacAddr: hns[j].MacAddr,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1036,7 +1036,7 @@ func (swire *SWire) GetCandidateNetworkForIp(ctx context.Context, userCred mccli
|
||||
}
|
||||
netPublics, err := swire.getPublicNetworks(ctx, userCred, ownerId, scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "swire.getPublicNetworks %s", swire.GetId())
|
||||
}
|
||||
for _, net := range netPublics {
|
||||
if net.IsAddressInRange(ip) {
|
||||
@@ -1046,6 +1046,32 @@ func (swire *SWire) GetCandidateNetworkForIp(ctx context.Context, userCred mccli
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (swire *SWire) GetCandidateNetworkForIp6(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, ip6Addr string) (*SNetwork, error) {
|
||||
ip6, err := netutils.NewIPV6Addr(ip6Addr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "netutils.NewIPV6Addr: %s", ip6Addr)
|
||||
}
|
||||
netPrivates, err := swire.getPrivateNetworks(ctx, userCred, ownerId, scope)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "swire.getPrivateNetworks %s", swire.GetId())
|
||||
}
|
||||
for _, net := range netPrivates {
|
||||
if net.IsAddress6InRange(ip6) {
|
||||
return &net, nil
|
||||
}
|
||||
}
|
||||
netPublics, err := swire.getPublicNetworks(ctx, userCred, ownerId, scope)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "swire.getPublicNetworks %s", swire.GetId())
|
||||
}
|
||||
for _, net := range netPublics {
|
||||
if net.IsAddress6InRange(ip6) {
|
||||
return &net, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func ChooseNetworkByAddressCount(nets []*SNetwork) (*SNetwork, *SNetwork) {
|
||||
return chooseNetworkByAddressCount(nets)
|
||||
}
|
||||
@@ -1332,6 +1358,19 @@ func (manager *SWireManager) GetOnPremiseWireOfIp(ipAddr string) (*SWire, error)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SWireManager) GetOnPremiseWireOfIp6(ip6Addr string) (*SWire, error) {
|
||||
net, err := NetworkManager.GetOnPremiseNetworkOfIP6(ip6Addr, "", tristate.None)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wire, _ := net.GetWire()
|
||||
if wire != nil {
|
||||
return wire, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("Wire not found")
|
||||
}
|
||||
}
|
||||
|
||||
func (w *SWire) PerformMergeNetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeNetworkInput) (jsonutils.JSONObject, error) {
|
||||
return nil, w.StartMergeNetwork(ctx, userCred, "")
|
||||
}
|
||||
@@ -1855,6 +1894,7 @@ func (swire *SWire) GetDetailsTopology(ctx context.Context, userCred mcclient.To
|
||||
for j := range hns {
|
||||
host.Networks = append(host.Networks, api.HostnetworkTopologyOutput{
|
||||
IpAddr: hns[j].IpAddr,
|
||||
Ip6Addr: hns[j].Ip6Addr,
|
||||
MacAddr: hns[j].MacAddr,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/util/version"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
@@ -1588,7 +1589,7 @@ func (h *SHostInfo) updateOrCreateHost(hostId string) (*api.HostDetails, error)
|
||||
if options.HostOptions.EnableSsl {
|
||||
schema = "https"
|
||||
}
|
||||
if strings.Contains(masterIp, ":") {
|
||||
if regutils.MatchIP6Addr(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)
|
||||
@@ -1906,7 +1907,7 @@ func (h *SHostInfo) uploadNetworkInfo() error {
|
||||
|
||||
func (h *SHostInfo) doSendPhysicalNicInfo(nic *types.SNicDevInfo) error {
|
||||
log.Infof("upload physical nic: %s(%s)", nic.Dev, nic.Mac)
|
||||
_, err := h.doUploadNicInfoInternal(nic.Dev, nic.Mac.String(), 1, "", "", "", nic.Up != nil && *nic.Up)
|
||||
_, err := h.doUploadNicInfoInternal(nic.Dev, nic.Mac.String(), 1, "", "", "", "", nic.Up != nil && *nic.Up)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "doUploadNicInfoInternal")
|
||||
}
|
||||
@@ -1914,15 +1915,15 @@ func (h *SHostInfo) doSendPhysicalNicInfo(nic *types.SNicDevInfo) error {
|
||||
}
|
||||
|
||||
func (h *SHostInfo) doUploadNicInfo(nic *SNIC) (*api.HostDetails, error) {
|
||||
hostDetails, err := h.doUploadNicInfoInternal(nic.Inter, nic.BridgeDev.GetMac(), nic.BridgeDev.GetVlanId(), nic.Wire, nic.Bridge, nic.Ip, true)
|
||||
hostDetails, err := h.doUploadNicInfoInternal(nic.Inter, nic.BridgeDev.GetMac(), nic.BridgeDev.GetVlanId(), nic.Wire, nic.Bridge, nic.Ip, nic.Ip6, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "doUploadNicInfoInternal")
|
||||
}
|
||||
return hostDetails, nil
|
||||
}
|
||||
|
||||
func (h *SHostInfo) doUploadNicInfoInternal(ifname, mac string, vlanId int, wire, bridge, ipaddr string, isUp bool) (*api.HostDetails, error) {
|
||||
log.Infof("Upload NIC br:%s if:%s", bridge, ifname)
|
||||
func (h *SHostInfo) doUploadNicInfoInternal(ifname, mac string, vlanId int, wire, bridge, ipaddr, ip6addr string, isUp bool) (*api.HostDetails, error) {
|
||||
log.Infof("Upload NIC br:%s if:%s ip:%s ip6:%s", bridge, ifname, ipaddr, ip6addr)
|
||||
content := jsonutils.NewDict()
|
||||
content.Set("mac", jsonutils.NewString(mac))
|
||||
content.Set("vlan_id", jsonutils.NewInt(int64(vlanId)))
|
||||
@@ -1942,6 +1943,14 @@ func (h *SHostInfo) doUploadNicInfoInternal(ifname, mac string, vlanId int, wire
|
||||
// always try to allocate from reserved pool
|
||||
content.Set("reserve", jsonutils.JSONTrue)
|
||||
}
|
||||
if len(ip6addr) > 0 {
|
||||
content.Set("ip6_addr", jsonutils.NewString(ip6addr))
|
||||
if ip6addr == h.GetMasterIp() {
|
||||
content.Set("nic_type", jsonutils.NewString(string(api.NIC_TYPE_ADMIN)))
|
||||
}
|
||||
// always try to allocate from reserved pool
|
||||
content.Set("reserve", jsonutils.JSONTrue)
|
||||
}
|
||||
res, err := modules.Hosts.PerformAction(h.GetSession(), h.HostId, "add-netif", content)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "modules.Hosts.PerformAction add-netif: %s", content.String())
|
||||
|
||||
@@ -28,7 +28,7 @@ func init() {
|
||||
"baremetalnetwork",
|
||||
"baremetalnetworks",
|
||||
[]string{"Baremetal_ID", "Host",
|
||||
"Network_ID", "Network", "IP_addr", "Mac_addr",
|
||||
"Network_ID", "Network", "IP_addr", "IP6_addr", "Mac_addr",
|
||||
"Nic_Type"},
|
||||
[]string{},
|
||||
&Hosts,
|
||||
|
||||
@@ -167,7 +167,8 @@ var (
|
||||
|
||||
func init() {
|
||||
Hosts = HostManager{modules.NewComputeManager("host", "hosts",
|
||||
[]string{"ID", "Name", "Access_mac", "Access_ip", "Ipmi_Ip", "Ovn_Mapped_Ip_Addr",
|
||||
[]string{"ID", "Name", "Access_mac", "Access_ip", "Ipmi_Ip",
|
||||
"Ovn_Mapped_Ip_Addr", "Ovn_Mapped_Ip6_Addr",
|
||||
"Manager_URI",
|
||||
"Status", "enabled", "host_status",
|
||||
"Guests", "Running_guests",
|
||||
|
||||
+3
-2
@@ -21,6 +21,7 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -75,7 +76,7 @@ func (conf ClientConfig) Connect() (*ssh.Client, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
|
||||
addr := net.JoinHostPort(conf.Host, strconv.Itoa(conf.Port))
|
||||
client, err := ssh.Dial("tcp", addr, cliConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -89,7 +90,7 @@ func (conf ClientConfig) ConnectContext(ctx context.Context) (*ssh.Client, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
|
||||
addr := net.JoinHostPort(conf.Host, strconv.Itoa(conf.Port))
|
||||
d := &net.Dialer{}
|
||||
netconn, err := d.DialContext(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
|
||||
+92
-39
@@ -122,9 +122,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
|
||||
Name: vpcExtLsName(vpc.Id),
|
||||
}
|
||||
vpcR1extp = &ovn_nb.LogicalRouterPort{
|
||||
Name: vpcR1extpName(vpc.Id),
|
||||
Mac: apis.VpcInterExtMac1,
|
||||
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcInterExtIP1(), apis.VpcInterExtMask)},
|
||||
Name: vpcR1extpName(vpc.Id),
|
||||
Mac: apis.VpcInterExtMac1,
|
||||
Networks: []string{
|
||||
fmt.Sprintf("%s/%d", apis.VpcInterExtIP1(), apis.VpcInterExtMask),
|
||||
fmt.Sprintf("%s/%d", apis.VpcInterExtIP16(), apis.VpcInterExtMask6),
|
||||
},
|
||||
}
|
||||
vpcExtr1p = &ovn_nb.LogicalSwitchPort{
|
||||
Name: vpcExtr1pName(vpc.Id),
|
||||
@@ -135,9 +138,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
|
||||
},
|
||||
}
|
||||
vpcR2extp = &ovn_nb.LogicalRouterPort{
|
||||
Name: vpcR2extpName(vpc.Id),
|
||||
Mac: apis.VpcInterExtMac2,
|
||||
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcInterExtIP2(), apis.VpcInterExtMask)},
|
||||
Name: vpcR2extpName(vpc.Id),
|
||||
Mac: apis.VpcInterExtMac2,
|
||||
Networks: []string{
|
||||
fmt.Sprintf("%s/%d", apis.VpcInterExtIP2(), apis.VpcInterExtMask),
|
||||
fmt.Sprintf("%s/%d", apis.VpcInterExtIP26(), apis.VpcInterExtMask6),
|
||||
},
|
||||
}
|
||||
vpcExtr2p = &ovn_nb.LogicalSwitchPort{
|
||||
Name: vpcExtr2pName(vpc.Id),
|
||||
@@ -175,9 +181,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
|
||||
Name: vpcHostLsName(vpc.Id),
|
||||
}
|
||||
vpcRhp = &ovn_nb.LogicalRouterPort{
|
||||
Name: vpcRhpName(vpc.Id),
|
||||
Mac: apis.VpcMappedGatewayMac,
|
||||
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcMappedGatewayIP(), apis.VpcMappedIPMask)},
|
||||
Name: vpcRhpName(vpc.Id),
|
||||
Mac: apis.VpcMappedGatewayMac,
|
||||
Networks: []string{
|
||||
fmt.Sprintf("%s/%d", apis.VpcMappedGatewayIP(), apis.VpcMappedIPMask),
|
||||
fmt.Sprintf("%s/%d", apis.VpcMappedGatewayIP6(), apis.VpcMappedIPMask6),
|
||||
},
|
||||
}
|
||||
vpcHrp = &ovn_nb.LogicalSwitchPort{
|
||||
Name: vpcHrpName(vpc.Id),
|
||||
@@ -205,9 +214,12 @@ func (keeper *OVNNorthboundKeeper) ClaimVpc(ctx context.Context, vpc *agentmodel
|
||||
Name: vpcEipLsName(vpc.Id),
|
||||
}
|
||||
vpcRep = &ovn_nb.LogicalRouterPort{
|
||||
Name: vpcRepName(vpc.Id),
|
||||
Mac: apis.VpcEipGatewayMac,
|
||||
Networks: []string{fmt.Sprintf("%s/%d", apis.VpcEipGatewayIP(), apis.VpcEipGatewayIPMask)},
|
||||
Name: vpcRepName(vpc.Id),
|
||||
Mac: apis.VpcEipGatewayMac,
|
||||
Networks: []string{
|
||||
fmt.Sprintf("%s/%d", apis.VpcEipGatewayIP(), apis.VpcEipGatewayIPMask),
|
||||
fmt.Sprintf("%s/%d", apis.VpcEipGatewayIP6(), apis.VpcEipGatewayIPMask6),
|
||||
},
|
||||
}
|
||||
vpcErp = &ovn_nb.LogicalSwitchPort{
|
||||
Name: vpcErpName(vpc.Id),
|
||||
@@ -265,7 +277,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
vpc = network.Vpc
|
||||
rpMac = mac.HashSubnetRouterPortMac(network.Id)
|
||||
mdMac = mac.HashSubnetMetadataMac(network.Id)
|
||||
mdIp = "169.254.169.254"
|
||||
// mdIp = "169.254.169.254"
|
||||
)
|
||||
netLs := &ovn_nb.LogicalSwitch{
|
||||
Name: netLsName(network.Id),
|
||||
@@ -275,16 +287,22 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
}
|
||||
if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
|
||||
networks = append(networks, fmt.Sprintf("%s/%d", network.GuestGateway6, network.GuestIp6Mask))
|
||||
for _, ip6 := range opts.MetadataServerIp6s {
|
||||
networks = append(networks, fmt.Sprintf("%s/128", ip6))
|
||||
}
|
||||
}
|
||||
netRnp := &ovn_nb.LogicalRouterPort{
|
||||
Name: netRnpName(network.Id),
|
||||
Mac: rpMac,
|
||||
Networks: networks,
|
||||
}
|
||||
mtu := opts.OvnUnderlayMtu
|
||||
mtu -= apis.VPC_OVN_ENCAP_COST
|
||||
if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
|
||||
netRnp.Ipv6RaConfigs = map[string]string{
|
||||
"address_mode": "dhcpv6_stateful",
|
||||
// "send_periodic": "false",
|
||||
"address_mode": "dhcpv6_stateful",
|
||||
"mtu": fmt.Sprintf("%d", mtu),
|
||||
"send_periodic": "true",
|
||||
}
|
||||
}
|
||||
netNrp := &ovn_nb.LogicalSwitchPort{
|
||||
@@ -295,10 +313,13 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
"router-port": netRnpName(network.Id),
|
||||
},
|
||||
}
|
||||
netMdpAddrs := []string{mdMac}
|
||||
netMdpAddrs = append(netMdpAddrs, opts.MetadataServerIp4s...)
|
||||
netMdpAddrs = append(netMdpAddrs, opts.MetadataServerIp6s...)
|
||||
netMdp := &ovn_nb.LogicalSwitchPort{
|
||||
Name: netMdpName(network.Id),
|
||||
Type: "localport",
|
||||
Addresses: []string{fmt.Sprintf("%s %s", mdMac, mdIp)},
|
||||
Addresses: []string{strings.Join(netMdpAddrs, " ")},
|
||||
}
|
||||
var (
|
||||
vpcExtBackRoute *ovn_nb.LogicalRouterStaticRoute
|
||||
@@ -306,7 +327,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
vpcExtBackRoute6 *ovn_nb.LogicalRouterStaticRoute
|
||||
vpcExtBackRoute6IdRef string
|
||||
)
|
||||
{
|
||||
if len(network.GuestGateway) > 0 && network.GuestIpMask > 0 {
|
||||
if ipAddr, err := netutils.NewIPV4Addr(network.GuestGateway); err != nil {
|
||||
return errors.Wrap(err, "NewIPV4Addr GuestGateway")
|
||||
} else {
|
||||
@@ -325,7 +346,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
vpcExtBackRouteIdRef = "vpcExtBackRoute"
|
||||
}
|
||||
}
|
||||
/*if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
|
||||
if len(network.GuestGateway6) > 0 && network.GuestIp6Mask > 0 {
|
||||
if ip6Addr, err := netutils.NewIPV6Addr(network.GuestGateway6); err != nil {
|
||||
return errors.Wrap(err, "NewIPV6Addr GuestGateway6")
|
||||
} else {
|
||||
@@ -335,7 +356,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
vpcExtBackRoute6 = &ovn_nb.LogicalRouterStaticRoute{
|
||||
Policy: ptr("dst-ip"),
|
||||
IpPrefix: netAddrCidr6,
|
||||
Nexthop: apis.VpcInterExtIP1().String(),
|
||||
Nexthop: apis.VpcInterExtIP16().String(),
|
||||
OutputPort: ptr(vpcR2extpName(vpc.Id)),
|
||||
ExternalIds: map[string]string{
|
||||
externalKeyOcRef: ocStaticRoute6Ref,
|
||||
@@ -343,7 +364,7 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
}
|
||||
vpcExtBackRoute6IdRef = "vpcExtBackRoute6"
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
var (
|
||||
args []string
|
||||
@@ -354,7 +375,9 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
netRnp,
|
||||
netNrp,
|
||||
netMdp,
|
||||
vpcExtBackRoute,
|
||||
}
|
||||
if vpcExtBackRoute != nil {
|
||||
irows = append(irows, vpcExtBackRoute)
|
||||
}
|
||||
if vpcExtBackRoute6 != nil {
|
||||
irows = append(irows, vpcExtBackRoute6)
|
||||
@@ -368,13 +391,17 @@ func (keeper *OVNNorthboundKeeper) ClaimNetwork(ctx context.Context, network *ag
|
||||
args = append(args, ovnCreateArgs(netRnp, netRnp.Name)...)
|
||||
args = append(args, ovnCreateArgs(netNrp, netNrp.Name)...)
|
||||
args = append(args, ovnCreateArgs(netMdp, netMdp.Name)...)
|
||||
args = append(args, ovnCreateArgs(vpcExtBackRoute, vpcExtBackRouteIdRef)...)
|
||||
if vpcExtBackRoute != nil {
|
||||
args = append(args, ovnCreateArgs(vpcExtBackRoute, vpcExtBackRouteIdRef)...)
|
||||
}
|
||||
if vpcExtBackRoute6 != nil {
|
||||
args = append(args, ovnCreateArgs(vpcExtBackRoute6, vpcExtBackRoute6IdRef)...)
|
||||
}
|
||||
args = append(args, "--", "add", "Logical_Switch", netLs.Name, "ports", "@"+netNrp.Name, "@"+netMdp.Name)
|
||||
args = append(args, "--", "add", "Logical_Router", vpcLrName(vpc.Id), "ports", "@"+netRnp.Name)
|
||||
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@"+vpcExtBackRouteIdRef)
|
||||
if vpcExtBackRoute != nil {
|
||||
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@"+vpcExtBackRouteIdRef)
|
||||
}
|
||||
if vpcExtBackRoute6 != nil {
|
||||
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@"+vpcExtBackRoute6IdRef)
|
||||
}
|
||||
@@ -387,7 +414,7 @@ func (keeper *OVNNorthboundKeeper) ClaimVpcHost(ctx context.Context, vpc *agentm
|
||||
)
|
||||
vpcHostLsp := &ovn_nb.LogicalSwitchPort{
|
||||
Name: vpcHostLspName(vpc.Id, host.Id),
|
||||
Addresses: []string{fmt.Sprintf("%s %s", mac.HashVpcHostDistgwMac(host.Id), host.OvnMappedIpAddr)},
|
||||
Addresses: []string{fmt.Sprintf("%s %s %s", mac.HashVpcHostDistgwMac(host.Id), host.OvnMappedIpAddr, host.OvnMappedIp6Addr)},
|
||||
}
|
||||
if m := keeper.DB.LogicalSwitchPort.FindOneMatchNonZeros(vpcHostLsp); m != nil {
|
||||
m.SetExternalId(externalKeyOcVersion, ocVersion)
|
||||
@@ -413,10 +440,11 @@ func (keeper *OVNNorthboundKeeper) ClaimVpcEipgw(ctx context.Context, vpc *agent
|
||||
var (
|
||||
ocVersion = fmt.Sprintf("%s.%d", vpc.UpdatedAt, vpc.UpdateVersion)
|
||||
eipgwVip = apis.VpcEipGatewayIP3().String()
|
||||
eipgwVip6 = apis.VpcEipGatewayIP63().String()
|
||||
)
|
||||
vpcEipLsp := &ovn_nb.LogicalSwitchPort{
|
||||
Name: vpcEipLspName(vpc.Id, eipgwVip),
|
||||
Addresses: []string{fmt.Sprintf("%s %s", apis.VpcEipGatewayMac3, eipgwVip)},
|
||||
Addresses: []string{fmt.Sprintf("%s %s %s", apis.VpcEipGatewayMac3, eipgwVip, eipgwVip6)},
|
||||
}
|
||||
if m := keeper.DB.LogicalSwitchPort.FindOneMatchNonZeros(vpcEipLsp); m != nil {
|
||||
m.SetExternalId(externalKeyOcVersion, ocVersion)
|
||||
@@ -457,7 +485,7 @@ func generateDhcpOptions(ctx context.Context, guestnetwork *agentmodels.Guestnet
|
||||
var (
|
||||
network = guestnetwork.Network
|
||||
dhcpMac = mac.HashSubnetDhcpMac(network.Id)
|
||||
mdIp = "169.254.169.254/32"
|
||||
mdIp = fmt.Sprintf("%s/32", opts.MetadataServerIp4s[0])
|
||||
|
||||
ocDhcpRef = fmt.Sprintf("dhcp/%s/%s", guestnetwork.GuestId, guestnetwork.Ifname)
|
||||
)
|
||||
@@ -618,6 +646,8 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
ocAclRef = fmt.Sprintf("acl/%s/%s/%s", network.Id, guestnetwork.GuestId, guestnetwork.Ifname)
|
||||
ocQosRef = fmt.Sprintf("qos/%s/%s/%s", network.Id, guestnetwork.GuestId, guestnetwork.Ifname)
|
||||
ocQosEipRef = fmt.Sprintf("qos-eip/%s/%s/%s/v2", vpc.Id, guestnetwork.GuestId, guestnetwork.Ifname)
|
||||
|
||||
ocGnrDefault6Ref = fmt.Sprintf("gnrDefault6/%s/%s/%s", vpc.Id, guestnetwork.GuestId, guestnetwork.Ifname)
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -708,10 +738,11 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
}
|
||||
|
||||
var (
|
||||
gnrDefault *ovn_nb.LogicalRouterStaticRoute
|
||||
qosEipIn *ovn_nb.QoS
|
||||
qosEipOut *ovn_nb.QoS
|
||||
hasQoSEip bool
|
||||
gnrDefault *ovn_nb.LogicalRouterStaticRoute
|
||||
gnrDefault6 *ovn_nb.LogicalRouterStaticRoute
|
||||
qosEipIn *ovn_nb.QoS
|
||||
qosEipOut *ovn_nb.QoS
|
||||
hasQoSEip bool
|
||||
)
|
||||
{
|
||||
gnrDefaultPolicy := "src-ip"
|
||||
@@ -759,14 +790,27 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
}
|
||||
|
||||
} else if vpcHasDistgw(vpc) {
|
||||
gnrDefault = &ovn_nb.LogicalRouterStaticRoute{
|
||||
Policy: &gnrDefaultPolicy,
|
||||
IpPrefix: guestnetwork.IpAddr + "/32",
|
||||
Nexthop: host.OvnMappedIpAddr,
|
||||
OutputPort: ptr(vpcRhpName(vpc.Id)),
|
||||
ExternalIds: map[string]string{
|
||||
externalKeyOcRef: ocGnrDefaultRef,
|
||||
},
|
||||
if len(guestnetwork.IpAddr) > 0 {
|
||||
gnrDefault = &ovn_nb.LogicalRouterStaticRoute{
|
||||
Policy: &gnrDefaultPolicy,
|
||||
IpPrefix: guestnetwork.IpAddr + "/32",
|
||||
Nexthop: host.OvnMappedIpAddr,
|
||||
OutputPort: ptr(vpcRhpName(vpc.Id)),
|
||||
ExternalIds: map[string]string{
|
||||
externalKeyOcRef: ocGnrDefaultRef,
|
||||
},
|
||||
}
|
||||
}
|
||||
if len(guestnetwork.Ip6Addr) > 0 {
|
||||
gnrDefault6 = &ovn_nb.LogicalRouterStaticRoute{
|
||||
Policy: &gnrDefaultPolicy,
|
||||
IpPrefix: guestnetwork.Ip6Addr + "/32",
|
||||
Nexthop: host.OvnMappedIp6Addr,
|
||||
OutputPort: ptr(vpcRhpName(vpc.Id)),
|
||||
ExternalIds: map[string]string{
|
||||
externalKeyOcRef: ocGnrDefault6Ref,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -794,7 +838,9 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
|
||||
irows := []types.IRow{
|
||||
gnp,
|
||||
dhcpOpt,
|
||||
}
|
||||
if len(guestnetwork.IpAddr) > 0 {
|
||||
irows = append(irows, dhcpOpt)
|
||||
}
|
||||
if len(guestnetwork.Ip6Addr) > 0 {
|
||||
irows = append(irows, dhcp6Opt)
|
||||
@@ -802,6 +848,9 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
if gnrDefault != nil {
|
||||
irows = append(irows, gnrDefault)
|
||||
}
|
||||
if gnrDefault6 != nil {
|
||||
irows = append(irows, gnrDefault6)
|
||||
}
|
||||
for _, acl := range acls {
|
||||
irows = append(irows, acl)
|
||||
}
|
||||
@@ -828,6 +877,10 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
args = append(args, ovnCreateArgs(gnrDefault, "gnrDefault")...)
|
||||
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@gnrDefault")
|
||||
}
|
||||
if gnrDefault6 != nil {
|
||||
args = append(args, ovnCreateArgs(gnrDefault6, "gnrDefault6")...)
|
||||
args = append(args, "--", "add", "Logical_Router", vpcExtLrName(vpc.Id), "static_routes", "@gnrDefault6")
|
||||
}
|
||||
for i, acl := range acls {
|
||||
ref := fmt.Sprintf("acl%d", i)
|
||||
args = append(args, ovnCreateArgs(acl, ref)...)
|
||||
|
||||
@@ -16,7 +16,8 @@ package helper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
@@ -82,7 +83,7 @@ func GetValidPrivateKey(host string, port int, username string, projectId string
|
||||
ssh.PublicKeys(signer),
|
||||
},
|
||||
}
|
||||
addr := fmt.Sprintf("%s:%d", host, port)
|
||||
addr := net.JoinHostPort(host, strconv.Itoa(port))
|
||||
client, err := ssh.Dial("tcp", addr, config)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "dial %s by %s", addr, username))
|
||||
|
||||
@@ -254,6 +254,7 @@ func handleSshShell(ctx context.Context, w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
func handleSshSession(ctx context.Context, session *session.SSshSession, w http.ResponseWriter) {
|
||||
log.Infof("handleSshSession %s", jsonutils.Marshal(session).String())
|
||||
handleDataSession(ctx, session, w, "ws", nil, false)
|
||||
}
|
||||
|
||||
|
||||
@@ -107,15 +107,13 @@ func resolveServerIPPortById(ctx context.Context, s *mcclient.ClientSession, id
|
||||
ip = guestNicDetails.EipAddr
|
||||
} else if len(guestNicDetails.IpAddr) > 0 {
|
||||
ip = guestNicDetails.IpAddr
|
||||
} else if len(guestNicDetails.Ip6Addr) > 0 {
|
||||
ip = guestNicDetails.Ip6Addr
|
||||
} else {
|
||||
return "", 0, nil, errors.Wrap(httperrors.ErrNotSupported, "no valid ipv4 addr")
|
||||
}
|
||||
}
|
||||
|
||||
if ip == guestNicDetails.Ip6Addr {
|
||||
return "", 0, nil, errors.Wrap(httperrors.ErrNotSupported, "ipv6 not supported")
|
||||
}
|
||||
|
||||
if ip == guestNicDetails.IpAddr && len(guestNicDetails.MappedIpAddr) > 0 {
|
||||
// need to do open forward
|
||||
ip, port, err = acquireForward(ctx, s, guestDetails.Id, ip, "tcp", port)
|
||||
|
||||
@@ -16,8 +16,9 @@ package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
@@ -111,7 +112,7 @@ func (s *SSshSession) IsNeedLogin() (bool, error) {
|
||||
ssh.Password(s.Password),
|
||||
},
|
||||
}
|
||||
addr := fmt.Sprintf("%s:%d", s.Host, s.Port)
|
||||
addr := net.JoinHostPort(s.Host, strconv.Itoa(s.Port))
|
||||
client, err := ssh.Dial("tcp", addr, config)
|
||||
if err != nil {
|
||||
return true, err
|
||||
|
||||
Reference in New Issue
Block a user