fix: server nic add subips

This commit is contained in:
Qiu Jian
2023-09-19 08:52:39 +08:00
parent 3f13107cb5
commit 7b3e2b1531
9 changed files with 300 additions and 148 deletions

View File

@@ -22,8 +22,8 @@ import (
func init() {
cmd := shell.NewResourceCmd(&modules.NetworkAddresses).WithContextManager(&modules.Wires)
cmd.BatchCreate(&options.NetworkAddressCreateOptions{})
// cmd.BatchCreate(&options.NetworkAddressCreateOptions{})
cmd.List(&options.NetworkAddressListOptions{})
cmd.Show(&options.NetworkAddressIdOptions{})
cmd.Delete(&options.NetworkAddressIdOptions{})
cmd.BatchDelete(&options.NetworkAddressIdsOptions{})
}

View File

@@ -119,6 +119,7 @@ func init() {
cmd.Perform("set-boot-index", &options.ServerSetBootIndexOptions{})
cmd.Perform("reset-nic-traffic-limit", &options.ServerNicTrafficLimitOptions{})
cmd.Perform("set-nic-traffic-limit", &options.ServerNicTrafficLimitOptions{})
cmd.Perform("add-sub-ips", &options.ServerAddSubIpsOptions{})
cmd.Get("vnc", new(options.ServerVncOptions))
cmd.Get("desc", new(options.ServerIdOptions))

View File

@@ -31,6 +31,8 @@ type GuestnetworkDetails struct {
// EipAddr associate with this guestnetwork
EipAddr string `json:"eip_addr"`
NetworkAddresses []NetworkAddrConf `json:"network_addresses"`
}
type GuestnetworkShortDesc struct {

View File

@@ -1029,3 +1029,22 @@ type ServerNicTrafficLimit struct {
RxTrafficLimit *int64 `json:"rx_traffic_limit"`
TxTrafficLimit *int64 `json:"tx_traffic_limit"`
}
type GuestAddSubIpsInput struct {
Mac string `json:"mac"`
IpAddr string `json:"ip_addr"`
Count int `json:"count"`
SubIps []string `json:"sub_ips"`
Reserved bool `json:"reserved"`
AllocDir IPAllocationDirection `json:"alloc_dir"`
}
type NetworkAddrConf struct {
Id string `json:"id"`
Type string `json:"type"`
IpAddr string `json:"ip_addr"`
Masklen int `json:"masklen"`
Gateway string `json:"gateway"`
}

View File

@@ -45,7 +45,8 @@ type NetworkAddressCreateInput struct {
Type string
NetworkId string
IPAddr string
IPAddr string `json:"ip_addr"`
IPAddrs []string `json:"ip_addrs"`
}
type NetworkAddressListInput struct {

View File

@@ -112,12 +112,12 @@ type SGuestnetwork struct {
EipId string `width:"36" charset:"ascii" nullable:"true" list:"user"`
}
func (self SGuestnetwork) GetIP() string {
return self.IpAddr
func (gn SGuestnetwork) GetIP() string {
return gn.IpAddr
}
func (self SGuestnetwork) GetMAC() string {
return self.MacAddr
func (gn SGuestnetwork) GetMAC() string {
return gn.MacAddr
}
func (manager *SGuestnetworkManager) GetSlaveFieldName() string {
@@ -142,6 +142,12 @@ func (manager *SGuestnetworkManager) FetchCustomizeColumns(
GuestJointResourceDetails: guestRows[i],
}
netIds[i] = objs[i].(*SGuestnetwork).NetworkId
ipnets, err := NetworkAddressManager.fetchAddressesByGuestnetworkId(objs[i].(*SGuestnetwork).RowId)
if err != nil {
log.Errorln(err)
} else if len(ipnets) > 0 {
rows[i].NetworkAddresses = ipnets
}
iNet, _ := NetworkManager.FetchById(netIds[i])
net := iNet.(*SNetwork)
rows[i].WireId = net.WireId
@@ -360,7 +366,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
return &gn, nil
}
func (self *SGuestnetwork) generateIfname(network *SNetwork, virtual bool, randomized bool) string {
func (gn *SGuestnetwork) generateIfname(network *SNetwork, virtual bool, randomized bool) string {
// It may happen that external networks when synced can miss ifname hint
network.ensureIfnameHint()
@@ -372,7 +378,7 @@ func (self *SGuestnetwork) generateIfname(network *SNetwork, virtual bool, rando
if virtual {
return fmt.Sprintf("%s-%s", nName, randutil.String(3))
} else {
ip, _ := netutils.NewIPV4Addr(self.IpAddr)
ip, _ := netutils.NewIPV4Addr(gn.IpAddr)
cliaddr := ip.CliAddr(network.GuestIpMask)
return fmt.Sprintf("%s-%d", nName, uint32(cliaddr))
}
@@ -407,18 +413,18 @@ func (man *SGuestnetworkManager) ifnameUsed(ifname string) bool {
return count > 0
}
func (self *SGuestnetwork) checkOrAllocateIfname(network *SNetwork, preferIfname string) (string, error) {
func (gn *SGuestnetwork) checkOrAllocateIfname(network *SNetwork, preferIfname string) (string, error) {
man := GuestnetworkManager
if !man.ifnameUsed(preferIfname) {
return preferIfname, nil
}
ifname := self.generateIfname(network, self.Virtual, false)
ifname := gn.generateIfname(network, gn.Virtual, false)
if !man.ifnameUsed(ifname) {
return ifname, nil
}
if !self.Virtual {
ifname = self.generateIfname(network, true, false)
if !gn.Virtual {
ifname = gn.generateIfname(network, true, false)
}
found := false
for i := 0; i < 5; i++ {
@@ -426,7 +432,7 @@ func (self *SGuestnetwork) checkOrAllocateIfname(network *SNetwork, preferIfname
found = true
break
}
ifname = self.generateIfname(network, true, true)
ifname = gn.generateIfname(network, true, true)
}
if !found {
return "", httperrors.NewConflictError("cannot allocate ifname")
@@ -434,8 +440,8 @@ func (self *SGuestnetwork) checkOrAllocateIfname(network *SNetwork, preferIfname
return ifname, nil
}
func (self *SGuestnetwork) GetGuest() *SGuest {
guest, _ := GuestManager.FetchById(self.GuestId)
func (gn *SGuestnetwork) GetGuest() *SGuest {
guest, _ := GuestManager.FetchById(gn.GuestId)
if guest != nil {
return guest.(*SGuest)
}
@@ -450,20 +456,20 @@ func (gn *SGuestnetwork) GetNetwork() *SNetwork {
return nil
}
func (self *SGuestnetwork) GetTeamGuestnetwork() (*SGuestnetwork, error) {
if len(self.TeamWith) > 0 {
return GuestnetworkManager.FetchByIdsAndIpMac(self.GuestId, self.NetworkId, "", self.TeamWith)
func (gn *SGuestnetwork) GetTeamGuestnetwork() (*SGuestnetwork, error) {
if len(gn.TeamWith) > 0 {
return GuestnetworkManager.FetchByIdsAndIpMac(gn.GuestId, gn.NetworkId, "", gn.TeamWith)
}
return nil, nil
}
func (self *SGuestnetwork) getJsonDescAtBaremetal(host *SHost) *api.GuestnetworkJsonDesc {
net := self.GetNetwork()
func (gn *SGuestnetwork) getJsonDescAtBaremetal(host *SHost) *api.GuestnetworkJsonDesc {
net := gn.GetNetwork()
netif := guestGetHostNetifFromNetwork(host, net)
if netif == nil {
log.Errorf("fail to find a valid net interface on baremetal %s for network %s", host.String(), net.String())
}
return self.getJsonDescHostwire(netif)
return gn.getJsonDescHostwire(netif)
}
func guestGetHostNetifFromNetwork(host *SHost, network *SNetwork) *SNetInterface {
@@ -479,13 +485,13 @@ func guestGetHostNetifFromNetwork(host *SHost, network *SNetwork) *SNetInterface
return netif
}
func (self *SGuestnetwork) getJsonDescAtHost(ctx context.Context, host *SHost) *api.GuestnetworkJsonDesc {
func (gn *SGuestnetwork) getJsonDescAtHost(ctx context.Context, host *SHost) *api.GuestnetworkJsonDesc {
var (
ret *api.GuestnetworkJsonDesc = nil
network = self.GetNetwork()
network = gn.GetNetwork()
)
if network.isOneCloudVpcNetwork() {
ret = self.getJsonDescOneCloudVpc(network)
ret = gn.getJsonDescOneCloudVpc(network)
} else {
netifs := host.getNetifsOnWire(network.WireId)
var netif *SNetInterface
@@ -499,10 +505,10 @@ func (self *SGuestnetwork) getJsonDescAtHost(ctx context.Context, host *SHost) *
log.Errorf("fail to find a bridged net_interface on host %s for network %s?????", host.String(), network.String())
netif = &netifs[0]
}
ret = self.getJsonDescHostwire(netif)
ret = gn.getJsonDescHostwire(netif)
}
{
ipnets, err := NetworkAddressManager.fetchAddressesByGuestnetworkId(ctx, self.RowId)
ipnets, err := NetworkAddressManager.fetchAddressesByGuestnetworkId(gn.RowId)
if err != nil {
log.Errorln(err)
}
@@ -513,8 +519,8 @@ func (self *SGuestnetwork) getJsonDescAtHost(ctx context.Context, host *SHost) *
return ret
}
func (self *SGuestnetwork) getJsonDescHostwire(netif *SNetInterface) *api.GuestnetworkJsonDesc {
desc := self.getJsonDesc()
func (gn *SGuestnetwork) getJsonDescHostwire(netif *SNetInterface) *api.GuestnetworkJsonDesc {
desc := gn.getJsonDesc()
if netif != nil {
desc.Bridge = netif.Bridge
desc.WireId = netif.WireId
@@ -523,50 +529,50 @@ func (self *SGuestnetwork) getJsonDescHostwire(netif *SNetInterface) *api.Guestn
return desc
}
func (self *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.GuestnetworkJsonDesc {
if self.MappedIpAddr == "" {
func (gn *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.GuestnetworkJsonDesc {
if gn.MappedIpAddr == "" {
var (
err error
addr string
)
addr, err = GuestnetworkManager.allocMappedIpAddr(context.TODO())
if err != nil {
log.Errorf("getJsonDescOneCloudVpc: row %d: alloc mapped ipaddr: %v", self.RowId, err)
log.Errorf("getJsonDescOneCloudVpc: row %d: alloc mapped ipaddr: %v", gn.RowId, err)
} else {
if _, err := db.Update(self, func() error {
self.MappedIpAddr = addr
if _, err := db.Update(gn, func() error {
gn.MappedIpAddr = addr
return nil
}); err != nil {
log.Errorf("getJsonDescOneCloudVpc: row %d: db update mapped addr: %v", self.RowId, err)
self.MappedIpAddr = ""
log.Errorf("getJsonDescOneCloudVpc: row %d: db update mapped addr: %v", gn.RowId, err)
gn.MappedIpAddr = ""
}
}
}
desc := self.getJsonDesc()
desc := gn.getJsonDesc()
vpc, _ := network.GetVpc()
desc.Vpc.Id = vpc.Id
desc.Vpc.Provider = api.VPC_PROVIDER_OVN
desc.Vpc.MappedIpAddr = self.MappedIpAddr
desc.Vpc.MappedIpAddr = gn.MappedIpAddr
return desc
}
func (self *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
net := self.GetNetwork()
func (gn *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
net := gn.GetNetwork()
desc := &api.GuestnetworkJsonDesc{
GuestnetworkBaseDesc: api.GuestnetworkBaseDesc{
Net: net.Name,
NetId: self.NetworkId,
Mac: self.MacAddr,
Virtual: self.Virtual,
NetId: gn.NetworkId,
Mac: gn.MacAddr,
Virtual: gn.Virtual,
},
}
if self.Virtual {
if len(self.TeamWith) > 0 {
teamGN, _ := self.GetTeamGuestnetwork()
if gn.Virtual {
if len(gn.TeamWith) > 0 {
teamGN, _ := gn.GetTeamGuestnetwork()
if teamGN != nil {
desc.Ip = teamGN.IpAddr
}
@@ -574,7 +580,7 @@ func (self *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
desc.Ip = net.GetNetAddr().String()
}
} else {
desc.Ip = self.IpAddr
desc.Ip = gn.IpAddr
}
desc.Gateway = net.GuestGateway
desc.Dns = net.GetDNS()
@@ -585,22 +591,22 @@ func (self *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
if routes != nil && len(routes) > 0 {
desc.Routes = jsonutils.Marshal(routes)
}
desc.Ifname = self.Ifname
desc.Ifname = gn.Ifname
desc.Masklen = net.GuestIpMask
desc.Driver = self.Driver
desc.NumQueues = self.NumQueues
desc.RxTrafficLimit = self.RxTrafficLimit
desc.TxTrafficLimit = self.TxTrafficLimit
desc.Driver = gn.Driver
desc.NumQueues = gn.NumQueues
desc.RxTrafficLimit = gn.RxTrafficLimit
desc.TxTrafficLimit = gn.TxTrafficLimit
desc.Vlan = net.VlanId
desc.Bw = self.getBandwidth()
desc.Mtu = self.getMtu(net)
desc.Index = self.Index
desc.VirtualIps = self.GetVirtualIPs()
desc.Bw = gn.getBandwidth()
desc.Mtu = gn.getMtu(net)
desc.Index = gn.Index
desc.VirtualIps = gn.GetVirtualIPs()
desc.ExternalId = net.ExternalId
desc.TeamWith = self.TeamWith
desc.TeamWith = gn.TeamWith
guest := self.getGuest()
if guest.GetHypervisor() != api.HYPERVISOR_KVM || self.IsSriovWithoutOffload() {
guest := gn.getGuest()
if guest.GetHypervisor() != api.HYPERVISOR_KVM || gn.IsSriovWithoutOffload() {
manual := true
desc.Manual = &manual
}
@@ -608,32 +614,32 @@ func (self *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
return desc
}
func (self *SGuestnetwork) IsSriovWithoutOffload() bool {
if self.Driver != api.NETWORK_DRIVER_VFIO {
func (gn *SGuestnetwork) IsSriovWithoutOffload() bool {
if gn.Driver != api.NETWORK_DRIVER_VFIO {
return false
}
if dev, _ := self.GetIsolatedDevice(); dev != nil && dev.OvsOffloadInterface != "" {
if dev, _ := gn.GetIsolatedDevice(); dev != nil && dev.OvsOffloadInterface != "" {
return false
}
return true
}
func (self *SGuestnetwork) UpdateNicTrafficUsed(rx, tx int64) error {
_, err := db.Update(self, func() error {
self.RxTrafficUsed = rx
self.TxTrafficUsed = tx
func (gn *SGuestnetwork) UpdateNicTrafficUsed(rx, tx int64) error {
_, err := db.Update(gn, func() error {
gn.RxTrafficUsed = rx
gn.TxTrafficUsed = tx
return nil
})
return err
}
func (self *SGuestnetwork) UpdateNicTrafficLimit(rx, tx *int64) error {
_, err := db.Update(self, func() error {
func (gn *SGuestnetwork) UpdateNicTrafficLimit(rx, tx *int64) error {
_, err := db.Update(gn, func() error {
if rx != nil {
self.RxTrafficLimit = *rx
gn.RxTrafficLimit = *rx
}
if tx != nil {
self.TxTrafficLimit = *tx
gn.TxTrafficLimit = *tx
}
return nil
})
@@ -657,13 +663,14 @@ func (manager *SGuestnetworkManager) GetGuestByAddress(address string) *SGuest {
return nil
}
func (self *SGuestnetwork) GetDetailedString() string {
network := self.GetNetwork()
return fmt.Sprintf("eth%d:%s/%d/%s/%d/%s/%s/%d", self.Index, self.IpAddr, network.GuestIpMask,
self.MacAddr, network.VlanId, network.Name, self.Driver, self.getBandwidth())
func (gn *SGuestnetwork) GetDetailedString() string {
network := gn.GetNetwork()
naCount, _ := NetworkAddressManager.fetchAddressCountByGuestnetworkId(gn.RowId)
return fmt.Sprintf("eth%d:%s/%d/%s/%d/%s/%s/%d/%d", gn.Index, gn.IpAddr, network.GuestIpMask,
gn.MacAddr, network.VlanId, network.Name, gn.Driver, gn.getBandwidth(), naCount)
}
func (self *SGuestnetwork) ValidateUpdateData(
func (gn *SGuestnetwork) ValidateUpdateData(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
@@ -672,8 +679,8 @@ func (self *SGuestnetwork) ValidateUpdateData(
if input.Index != nil {
index := *input.Index
q := GuestnetworkManager.Query().SubQuery()
count, err := q.Query().Filter(sqlchemy.Equals(q.Field("guest_id"), self.GuestId)).
Filter(sqlchemy.NotEquals(q.Field("network_id"), self.NetworkId)).
count, err := q.Query().Filter(sqlchemy.Equals(q.Field("guest_id"), gn.GuestId)).
Filter(sqlchemy.NotEquals(q.Field("network_id"), gn.NetworkId)).
Filter(sqlchemy.Equals(q.Field("index"), index)).CountWithError()
if err != nil {
return input, httperrors.NewInternalServerError("checkout nic index uniqueness fail %s", err)
@@ -683,7 +690,7 @@ func (self *SGuestnetwork) ValidateUpdateData(
}
}
var err error
input.GuestJointBaseUpdateInput, err = self.SGuestJointsBase.ValidateUpdateData(ctx, userCred, query, input.GuestJointBaseUpdateInput)
input.GuestJointBaseUpdateInput, err = gn.SGuestJointsBase.ValidateUpdateData(ctx, userCred, query, input.GuestJointBaseUpdateInput)
if err != nil {
return input, errors.Wrap(err, "SGuestJointsBase.ValidateUpdateData")
}
@@ -744,23 +751,23 @@ func (manager *SGuestnetworkManager) getGuestNicByIP(ip string, networkId string
return &gn, nil
}
func (self *SGuestnetwork) LogDetachEvent(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, network *SNetwork) {
func (gn *SGuestnetwork) LogDetachEvent(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, network *SNetwork) {
if network == nil {
netTmp, _ := NetworkManager.FetchById(self.NetworkId)
netTmp, _ := NetworkManager.FetchById(gn.NetworkId)
network = netTmp.(*SNetwork)
}
db.OpsLog.LogDetachEvent(ctx, guest, network, userCred, nil)
}
func (self *SGuestnetwork) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
if err := NetworkAddressManager.deleteByGuestnetworkId(ctx, userCred, self.RowId); err != nil {
func (gn *SGuestnetwork) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
if err := NetworkAddressManager.deleteByGuestnetworkId(ctx, userCred, gn.RowId); err != nil {
return errors.Wrap(err, "delete attached network addresses")
}
return db.DeleteModel(ctx, userCred, self)
return db.DeleteModel(ctx, userCred, gn)
}
func (self *SGuestnetwork) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, self)
func (gn *SGuestnetwork) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, gn)
}
func totalGuestNicCount(
@@ -837,28 +844,28 @@ func calculateNics(q *sqlchemy.SQuery) GuestnicsCount {
return cnt
}
func (self *SGuestnetwork) IsExit() bool {
if self.IpAddr != "" {
addr, err := netutils.NewIPV4Addr(self.IpAddr)
func (gn *SGuestnetwork) IsExit() bool {
if gn.IpAddr != "" {
addr, err := netutils.NewIPV4Addr(gn.IpAddr)
if err == nil {
return netutils.IsExitAddress(addr)
}
}
net := self.GetNetwork()
net := gn.GetNetwork()
if net != nil {
return net.IsExitNetwork()
}
return false
}
func (self *SGuestnetwork) getBandwidth() int {
if self.BwLimit == 0 {
func (gn *SGuestnetwork) getBandwidth() int {
if gn.BwLimit == 0 {
return 0
}
if self.BwLimit > 0 && self.BwLimit <= api.MAX_BANDWIDTH {
return self.BwLimit
if gn.BwLimit > 0 && gn.BwLimit <= api.MAX_BANDWIDTH {
return gn.BwLimit
} else {
net := self.GetNetwork()
net := gn.GetNetwork()
if net != nil {
wire, _ := net.GetWire()
if wire != nil {
@@ -869,14 +876,14 @@ func (self *SGuestnetwork) getBandwidth() int {
}
}
func (self *SGuestnetwork) getMtu(net *SNetwork) int16 {
func (gn *SGuestnetwork) getMtu(net *SNetwork) int16 {
return net.getMtu()
}
func (self *SGuestnetwork) IsAllocated() bool {
region, _ := self.GetGuest().getRegion()
func (gn *SGuestnetwork) IsAllocated() bool {
region, _ := gn.GetGuest().getRegion()
provider := region.Provider
if regutils.MatchMacAddr(self.MacAddr) && (self.Virtual || regutils.MatchIP4Addr(self.IpAddr) || (provider != api.CLOUD_PROVIDER_ONECLOUD && !options.Options.EnablePreAllocateIpAddr)) {
if regutils.MatchMacAddr(gn.MacAddr) && (gn.Virtual || regutils.MatchIP4Addr(gn.IpAddr) || (provider != api.CLOUD_PROVIDER_ONECLOUD && !options.Options.EnablePreAllocateIpAddr)) {
return true
}
return false
@@ -899,10 +906,10 @@ func GetIPTenantIdPairs() {
*/
}
func (self *SGuestnetwork) GetVirtualIPs() []string {
func (gn *SGuestnetwork) GetVirtualIPs() []string {
ips := make([]string, 0)
guest := self.GetGuest()
net := self.GetNetwork()
guest := gn.GetGuest()
net := gn.GetNetwork()
for _, guestgroup := range guest.GetGroups() {
group := guestgroup.GetGroup()
groupnets, err := group.GetNetworks()
@@ -919,9 +926,9 @@ func (self *SGuestnetwork) GetVirtualIPs() []string {
return ips
}
func (self *SGuestnetwork) GetIsolatedDevice() (*SIsolatedDevice, error) {
func (gn *SGuestnetwork) GetIsolatedDevice() (*SIsolatedDevice, error) {
dev := SIsolatedDevice{}
q := IsolatedDeviceManager.Query().Equals("guest_id", self.GuestId).Equals("network_index", self.Index)
q := IsolatedDeviceManager.Query().Equals("guest_id", gn.GuestId).Equals("network_index", gn.Index)
if cnt, err := q.CountWithError(); err != nil {
return nil, err
} else if cnt == 0 {
@@ -1021,39 +1028,39 @@ func (manager *SGuestnetworkManager) FetchByGuestIdIndex(guestId string, index i
return nil, errors.ErrNotFound
}
func (self *SGuestnetwork) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
func (gn *SGuestnetwork) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
desc := api.GuestnetworkShortDesc{}
if len(self.IpAddr) > 0 {
desc.IpAddr = self.IpAddr
desc.IsExit = self.IsExit()
if len(gn.IpAddr) > 0 {
desc.IpAddr = gn.IpAddr
desc.IsExit = gn.IsExit()
}
if len(self.Ip6Addr) > 0 {
desc.Ip6Addr = self.Ip6Addr
if len(gn.Ip6Addr) > 0 {
desc.Ip6Addr = gn.Ip6Addr
}
desc.Mac = self.MacAddr
if len(self.TeamWith) > 0 {
desc.TeamWith = self.TeamWith
desc.Mac = gn.MacAddr
if len(gn.TeamWith) > 0 {
desc.TeamWith = gn.TeamWith
}
return jsonutils.Marshal(desc).(*jsonutils.JSONDict)
}
func (self *SGuestnetwork) ToNetworkConfig() *api.NetworkConfig {
net := self.GetNetwork()
func (gn *SGuestnetwork) ToNetworkConfig() *api.NetworkConfig {
net := gn.GetNetwork()
if net == nil {
return nil
}
wire, _ := net.GetWire()
ret := &api.NetworkConfig{
Index: int(self.Index),
Index: int(gn.Index),
Network: net.Id,
Wire: wire.Id,
Mac: self.MacAddr,
Address: self.IpAddr,
Driver: self.Driver,
BwLimit: self.BwLimit,
Mac: gn.MacAddr,
Address: gn.IpAddr,
Driver: gn.Driver,
BwLimit: gn.BwLimit,
Project: net.ProjectId,
Domain: net.DomainId,
Ifname: self.Ifname,
Ifname: gn.Ifname,
NetType: net.ServerType,
Exit: net.IsExitNetwork(),
}
@@ -1081,7 +1088,11 @@ func (manager *SGuestnetworkManager) ListItemFilter(
q = q.In("mac_addr", query.MacAddr)
}
if len(query.IpAddr) > 0 {
q = q.In("ip_addr", query.IpAddr)
naSubQ := NetworkAddressManager.Query("parent_id").Equals("type", api.NetworkAddressTypeSubIP).Equals("parent_type", api.NetworkAddressParentTypeGuestnetwork).In("ip_addr", query.IpAddr).SubQuery()
q = q.Filter(sqlchemy.OR(
sqlchemy.In(q.Field("ip_addr"), query.IpAddr),
sqlchemy.In(q.Field("row_id"), naSubQ),
))
}
if len(query.Ip6Addr) > 0 {
q = q.In("ip6_addr", query.Ip6Addr)

View File

@@ -76,21 +76,21 @@ func (man *SNetworkAddressManager) InitializeData() error {
return nil
}
func (man *SNetworkAddressManager) queryByParentTypeId(ctx context.Context, typ string, id string) *sqlchemy.SQuery {
func (man *SNetworkAddressManager) queryByParentTypeId(typ string, id string) *sqlchemy.SQuery {
q := NetworkAddressManager.Query().
Equals("parent_type", typ).
Equals("parent_id", id)
return q
}
func (man *SNetworkAddressManager) queryByGuestnetworkId(ctx context.Context, rowid int64) *sqlchemy.SQuery {
func (man *SNetworkAddressManager) queryByGuestnetworkId(rowid int64) *sqlchemy.SQuery {
id := strconv.FormatInt(rowid, 10)
return man.queryByParentTypeId(ctx, api.NetworkAddressParentTypeGuestnetwork, id)
return man.queryByParentTypeId(api.NetworkAddressParentTypeGuestnetwork, id)
}
func (man *SNetworkAddressManager) fetchByParentTypeId(ctx context.Context, typ string, id string) ([]SNetworkAddress, error) {
func (man *SNetworkAddressManager) fetchByParentTypeId(typ string, id string) ([]SNetworkAddress, error) {
var (
q = man.queryByParentTypeId(ctx, typ, id)
q = man.queryByParentTypeId(typ, id)
nas []SNetworkAddress
)
if err := db.FetchModelObjects(man, q, &nas); err != nil {
@@ -99,23 +99,22 @@ func (man *SNetworkAddressManager) fetchByParentTypeId(ctx context.Context, typ
return nas, nil
}
func (man *SNetworkAddressManager) fetchByGuestnetworkId(ctx context.Context, rowid int64) ([]SNetworkAddress, error) {
func (man *SNetworkAddressManager) fetchByGuestnetworkId(rowid int64) ([]SNetworkAddress, error) {
id := strconv.FormatInt(rowid, 10)
return man.fetchByParentTypeId(ctx, api.NetworkAddressParentTypeGuestnetwork, id)
return man.fetchByParentTypeId(api.NetworkAddressParentTypeGuestnetwork, id)
}
type addrConf struct {
Type string `json:"type"`
IpAddr string `json:"ip_addr"`
Masklen int `json:"masklen"`
Gateway string `json:"gateway"`
func (man *SNetworkAddressManager) fetchAddressCountByGuestnetworkId(rowid int64) (int, error) {
q := man.queryByGuestnetworkId(rowid)
return q.CountWithError()
}
func (man *SNetworkAddressManager) fetchAddressesByGuestnetworkId(ctx context.Context, rowid int64) ([]addrConf, error) {
func (man *SNetworkAddressManager) fetchAddressesByGuestnetworkId(rowid int64) ([]api.NetworkAddrConf, error) {
var (
naq = man.queryByGuestnetworkId(ctx, rowid).SubQuery()
naq = man.queryByGuestnetworkId(rowid).SubQuery()
nq = NetworkManager.Query().SubQuery()
ipnetsq = naq.Query(
naq.Field("id"),
naq.Field("type"),
naq.Field("ip_addr"),
nq.Field("guest_ip_mask").Label("masklen"),
@@ -124,7 +123,7 @@ func (man *SNetworkAddressManager) fetchAddressesByGuestnetworkId(ctx context.Co
naq.Field("network_id"),
nq.Field("id")),
)
ipnets []addrConf
ipnets []api.NetworkAddrConf
)
if err := ipnetsq.All(&ipnets); err != nil {
return nil, errors.Wrapf(err, "fetch addresses ipnets by guestnetwork row id: %d", rowid)
@@ -133,7 +132,7 @@ func (man *SNetworkAddressManager) fetchAddressesByGuestnetworkId(ctx context.Co
}
func (man *SNetworkAddressManager) deleteByGuestnetworkId(ctx context.Context, userCred mcclient.TokenCredential, rowid int64) error {
nas, err := NetworkAddressManager.fetchByGuestnetworkId(ctx, rowid)
nas, err := NetworkAddressManager.fetchByGuestnetworkId(rowid)
if err != nil {
return errors.Wrap(err, "fetch attached network addresses")
}
@@ -164,7 +163,7 @@ func (man *SNetworkAddressManager) syncGuestnetworkICloudNic(ctx context.Context
}
func (man *SNetworkAddressManager) syncGuestnetworkSubIPs(ctx context.Context, userCred mcclient.TokenCredential, guestnetwork *SGuestnetwork, ipAddrs []string) error {
nas, err := man.fetchByGuestnetworkId(ctx, guestnetwork.RowId)
nas, err := man.fetchByGuestnetworkId(guestnetwork.RowId)
if err != nil {
return errors.Wrap(err, "fetchByGuestnetworkId")
}
@@ -207,7 +206,7 @@ func (man *SNetworkAddressManager) syncGuestnetworkSubIPs(ctx context.Context, u
}
func (man *SNetworkAddressManager) removeGuestnetworkSubIPs(ctx context.Context, userCred mcclient.TokenCredential, guestnetwork *SGuestnetwork, ipAddrs []string) error {
q := man.queryByGuestnetworkId(ctx, guestnetwork.RowId)
q := man.queryByGuestnetworkId(guestnetwork.RowId)
q = q.In("ip_addr", ipAddrs)
var nas []SNetworkAddress
@@ -262,7 +261,7 @@ func (man *SNetworkAddressManager) addGuestnetworkSubIPs(ctx context.Context, us
return nil
}
func (man *SNetworkAddressManager) BatchPreValidate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict, count int) error {
/*func (man *SNetworkAddressManager) BatchPreValidate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict, count int) error {
var (
input api.NetworkAddressCreateInput
err error
@@ -279,13 +278,14 @@ func (man *SNetworkAddressManager) BatchPreValidate(ctx context.Context, userCre
}
data.Update(input.JSON(input))
return nil
}
}*/
func (man *SNetworkAddressManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.NetworkAddressCreateInput) (api.NetworkAddressCreateInput, error) {
return man.validateCreateData(ctx, userCred, ownerId, query, input, 1)
// return man.validateCreateData(ctx, userCred, ownerId, query, input, 1)
return input, errors.Wrap(httperrors.ErrNotSupported, "no supported")
}
func (man *SNetworkAddressManager) validateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.NetworkAddressCreateInput, count int) (api.NetworkAddressCreateInput, error) {
/*func (man *SNetworkAddressManager) validateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.NetworkAddressCreateInput, count int) (api.NetworkAddressCreateInput, error) {
if _, err := man.SStandaloneAnonResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StandaloneAnonResourceCreateInput); err != nil {
return input, err
}
@@ -350,7 +350,7 @@ func (man *SNetworkAddressManager) validateCreateData(ctx context.Context, userC
}
return input, nil
}
}*/
func (na *SNetworkAddress) parentIdInt64() int64 {
r, err := strconv.ParseInt(na.ParentId, 10, 64)
@@ -420,7 +420,7 @@ func (na *SNetworkAddress) getICloudNic(ctx context.Context, userCred mcclient.T
return nil, errors.Wrapf(errors.ErrNotFound, "getICloudNic: no cloud nic with ip %s, mac %s", guestnetwork.IpAddr, guestnetwork.MacAddr)
}
func (na *SNetworkAddress) remoteAssignAddress(ctx context.Context, userCred mcclient.TokenCredential) error {
/*func (na *SNetworkAddress) remoteAssignAddress(ctx context.Context, userCred mcclient.TokenCredential) error {
if na.ParentType == api.NetworkAddressParentTypeGuestnetwork {
guest, err := na.getGuest(ctx, userCred)
if err != nil {
@@ -442,7 +442,7 @@ func (na *SNetworkAddress) remoteAssignAddress(ctx context.Context, userCred mcc
}
}
return nil
}
}*/
func (na *SNetworkAddress) remoteUnassignAddress(ctx context.Context, userCred mcclient.TokenCredential) error {
if na.ParentType == api.NetworkAddressParentTypeGuestnetwork {
@@ -471,12 +471,12 @@ func (na *SNetworkAddress) remoteUnassignAddress(ctx context.Context, userCred m
return nil
}
func (na *SNetworkAddress) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
/*func (na *SNetworkAddress) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
if err := na.remoteAssignAddress(ctx, userCred); err != nil {
return err
}
return nil
}
}*/
func (na *SNetworkAddress) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
if err := na.remoteUnassignAddress(ctx, userCred); err != nil {
@@ -651,3 +651,99 @@ func (man *SNetworkAddressManager) submitGuestSyncTask(ctx context.Context, user
},
})
}
func (g *SGuest) PerformAddSubIps(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.GuestAddSubIpsInput) (jsonutils.JSONObject, error) {
gn, err := g.getGuestnetworkByIpOrMac(input.IpAddr, input.Mac)
if err != nil {
return nil, errors.Wrapf(err, "getGuestnetworkByIpOrMac ip=%s mac=%s", input.IpAddr, input.Mac)
}
net := gn.GetNetwork()
if net == nil {
return nil, httperrors.NewInternalServerError("cannot fetch network of guestnetwork %d", gn.RowId)
}
if input.Count == 0 {
input.Count = len(input.SubIps)
}
if input.Count == 0 {
// nil operation
return nil, nil
}
subIps := make([]string, 0)
err = func() error {
lockman.LockObject(ctx, net)
defer lockman.ReleaseObject(ctx, net)
addrTable := net.GetUsedAddresses()
recentUsedAddrTable := GuestnetworkManager.getRecentlyReleasedIPAddresses(net.Id, net.getAllocTimoutDuration())
for i := 0; i < input.Count; i++ {
var candidate string
if i < len(input.SubIps) {
candidate = input.SubIps[i]
}
ipAddr, err := net.GetFreeIP(ctx, userCred, addrTable, recentUsedAddrTable, candidate, input.AllocDir, input.Reserved)
if err != nil {
return httperrors.NewInputParameterError("allocate ip addr: %v", err)
}
na := SNetworkAddress{}
na.ParentType = api.NetworkAddressParentTypeGuestnetwork
na.Type = api.NetworkAddressTypeSubIP
na.IpAddr = ipAddr
na.ParentId = fmt.Sprintf("%d", gn.RowId)
na.NetworkId = net.Id
na.SetModelManager(NetworkAddressManager, &na)
err = NetworkAddressManager.TableSpec().Insert(ctx, &na)
if err != nil {
return errors.Wrapf(err, "Insert Network Address %s", na.IpAddr)
}
subIps = append(subIps, ipAddr)
// update
addrTable[ipAddr] = true
}
return nil
}()
if err != nil {
return nil, errors.Wrap(err, "allocate")
}
if g.ExternalId != "" {
// sync to cloud
iNic, err := g.getICloudNic(ctx, gn)
if err != nil {
return nil, errors.Wrap(err, "getICloudNic")
}
if err := iNic.AssignAddress(subIps); err != nil {
if errors.Cause(err) == cloudprovider.ErrAddressCountExceed {
return nil, httperrors.NewNotAcceptableError("exceed address count limit: %v", err)
}
return nil, errors.Wrapf(err, "AssignAddress %s", subIps)
}
} else {
NetworkAddressManager.submitGuestSyncTask(ctx, userCred, g)
}
return nil, nil
}
func (g *SGuest) getICloudNic(ctx context.Context, gn *SGuestnetwork) (cloudprovider.ICloudNic, error) {
ivm, err := g.GetIVM(ctx)
if err != nil {
return nil, errors.Wrap(err, "GetIVM")
}
iNics, err := ivm.GetINics()
if err != nil {
return nil, errors.Wrap(err, "GetINics %s")
}
for _, iNic := range iNics {
if iNic.GetIP() == gn.IpAddr && iNic.GetMAC() == gn.MacAddr {
return iNic, nil
}
}
return nil, errors.Wrapf(errors.ErrNotFound, "no nic of ip %s mac %s", gn.IpAddr, gn.MacAddr)
}

View File

@@ -1391,3 +1391,13 @@ type ServerIsoOptions struct {
func (o *ServerIsoOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(o), nil
}
type ServerAddSubIpsOptions struct {
ServerIdOptions
computeapi.GuestAddSubIpsInput
}
func (o *ServerAddSubIpsOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(o), nil
}

View File

@@ -73,3 +73,15 @@ func (opts *NetworkAddressIdOptions) GetId() string {
func (opts *NetworkAddressIdOptions) Params() (jsonutils.JSONObject, error) {
return nil, nil
}
type NetworkAddressIdsOptions struct {
ID []string
}
func (opts *NetworkAddressIdsOptions) GetIds() []string {
return opts.ID
}
func (opts *NetworkAddressIdsOptions) Params() (jsonutils.JSONObject, error) {
return nil, nil
}