mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
Merge pull request #12682 from swordqiu/automated-cherry-pick-of-#12681-upstream-release-3.8
Automated cherry pick of #12681: fix: server-create-eip allocation prefer owner's eip network
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
@@ -1222,6 +1223,84 @@ func (self *SElasticip) getMoreDetails(out api.ElasticipDetails) api.ElasticipDe
|
||||
return out
|
||||
}
|
||||
|
||||
type SEipNetwork struct {
|
||||
owner mcclient.IIdentityProvider
|
||||
user mcclient.TokenCredential
|
||||
freeCnt int
|
||||
net *SNetwork
|
||||
}
|
||||
|
||||
func NewEipNetwork(net *SNetwork, owner mcclient.IIdentityProvider, user mcclient.TokenCredential, freecnt int) SEipNetwork {
|
||||
return SEipNetwork{
|
||||
owner: owner,
|
||||
user: user,
|
||||
freeCnt: freecnt,
|
||||
net: net,
|
||||
}
|
||||
}
|
||||
|
||||
func (en SEipNetwork) isOwnerProject() bool {
|
||||
return en.owner.GetProjectId() == en.net.ProjectId
|
||||
}
|
||||
|
||||
func (en SEipNetwork) isOwnerProjectDomain() bool {
|
||||
return en.owner.GetProjectDomainId() == en.net.DomainId
|
||||
}
|
||||
|
||||
func (en SEipNetwork) isUserProject() bool {
|
||||
return en.user.GetProjectId() == en.net.ProjectId
|
||||
}
|
||||
|
||||
func (en SEipNetwork) isUserProjectDomain() bool {
|
||||
return en.user.GetProjectDomainId() == en.net.DomainId
|
||||
}
|
||||
|
||||
func (en SEipNetwork) GetNetwork() *SNetwork {
|
||||
return en.net
|
||||
}
|
||||
|
||||
type SEipNetworks []SEipNetwork
|
||||
|
||||
func (a SEipNetworks) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a SEipNetworks) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
|
||||
func (a SEipNetworks) Less(i, j int) bool {
|
||||
if a[i].isOwnerProject() && !a[j].isOwnerProject() {
|
||||
return true
|
||||
} else if !a[i].isOwnerProject() && a[j].isOwnerProject() {
|
||||
return false
|
||||
}
|
||||
if a[i].isOwnerProjectDomain() && !a[j].isOwnerProjectDomain() {
|
||||
return true
|
||||
} else if !a[i].isOwnerProjectDomain() && a[j].isOwnerProjectDomain() {
|
||||
return false
|
||||
}
|
||||
if a[i].isUserProject() && !a[j].isUserProject() {
|
||||
return true
|
||||
} else if !a[i].isUserProject() && a[j].isUserProject() {
|
||||
return false
|
||||
}
|
||||
if a[i].isUserProjectDomain() && !a[j].isUserProjectDomain() {
|
||||
return true
|
||||
} else if !a[i].isUserProjectDomain() && a[j].isUserProjectDomain() {
|
||||
return false
|
||||
}
|
||||
if a[i].freeCnt > a[j].freeCnt {
|
||||
return true
|
||||
} else if a[i].freeCnt < a[j].freeCnt {
|
||||
return false
|
||||
}
|
||||
if a[i].net.Id < a[j].net.Id {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type NewEipForVMOnHostArgs struct {
|
||||
Bandwidth int
|
||||
BgpType string
|
||||
@@ -1274,13 +1353,14 @@ func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCre
|
||||
eip.Bandwidth = bw
|
||||
eip.ChargeType = chargeType
|
||||
eip.AutoDellocate = tristate.NewFromBool(autoDellocate)
|
||||
ownerCred := userCred.(mcclient.IIdentityProvider)
|
||||
if vm != nil {
|
||||
eip.DomainId = vm.DomainId
|
||||
eip.ProjectId = vm.ProjectId
|
||||
} else {
|
||||
eip.DomainId = userCred.GetProjectDomainId()
|
||||
eip.ProjectId = userCred.GetProjectId()
|
||||
ownerCred = vm.GetOwnerId()
|
||||
} else if nat != nil {
|
||||
ownerCred = nat.GetOwnerId()
|
||||
}
|
||||
eip.DomainId = ownerCred.GetProjectDomainId()
|
||||
eip.ProjectId = ownerCred.GetProjectId()
|
||||
eip.ProjectSrc = string(apis.OWNER_SOURCE_LOCAL)
|
||||
if host != nil {
|
||||
eip.ManagerId = host.ManagerId
|
||||
@@ -1313,21 +1393,21 @@ func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCre
|
||||
return nil, errors.Wrapf(err, "fetch eip networks usable in host %s(%s)",
|
||||
host.Name, host.Id)
|
||||
}
|
||||
var net *SNetwork
|
||||
eipNets := make([]SEipNetwork, 0)
|
||||
for i := range nets {
|
||||
net = &nets[i]
|
||||
cnt, err := net.GetFreeAddressCount()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
net := &nets[i]
|
||||
cnt, _ := net.GetFreeAddressCount()
|
||||
if cnt > 0 {
|
||||
break
|
||||
eipNets = append(eipNets, NewEipNetwork(net, ownerCred, userCred, cnt))
|
||||
}
|
||||
}
|
||||
if net == nil {
|
||||
return nil, errors.Error("no usable eip network")
|
||||
if len(eipNets) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("no usable eip network")
|
||||
}
|
||||
eip.NetworkId = net.Id
|
||||
// prefer networks with identical project, domain, more free address, Id
|
||||
sort.Sort(SEipNetworks(eipNets))
|
||||
log.Debugf("eipnets: %s", jsonutils.Marshal(eipNets))
|
||||
eip.NetworkId = eipNets[0].GetNetwork().Id
|
||||
}
|
||||
|
||||
var err = func() error {
|
||||
|
||||
@@ -917,52 +917,6 @@ func (self *SKVMRegionDriver) ValidateEipChargeType(chargeType string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type eipNetwork struct {
|
||||
owner mcclient.TokenCredential
|
||||
freeCnt int
|
||||
net *models.SNetwork
|
||||
}
|
||||
|
||||
func (en eipNetwork) isOwnerProject() bool {
|
||||
return en.owner.GetProjectId() == en.net.ProjectId
|
||||
}
|
||||
|
||||
func (en eipNetwork) isOwnerProjectDomain() bool {
|
||||
return en.owner.GetProjectDomainId() == en.net.DomainId
|
||||
}
|
||||
|
||||
type eipNetworks []eipNetwork
|
||||
|
||||
func (a eipNetworks) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a eipNetworks) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
|
||||
func (a eipNetworks) Less(i, j int) bool {
|
||||
if a[i].isOwnerProject() && !a[j].isOwnerProject() {
|
||||
return true
|
||||
} else if !a[i].isOwnerProject() && a[j].isOwnerProject() {
|
||||
return false
|
||||
}
|
||||
if a[i].isOwnerProjectDomain() && !a[j].isOwnerProjectDomain() {
|
||||
return true
|
||||
} else if !a[i].isOwnerProjectDomain() && a[j].isOwnerProjectDomain() {
|
||||
return false
|
||||
}
|
||||
if a[i].freeCnt > a[j].freeCnt {
|
||||
return true
|
||||
} else if a[i].freeCnt < a[j].freeCnt {
|
||||
return false
|
||||
}
|
||||
if a[i].net.Id < a[j].net.Id {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SKVMRegionDriver) ValidateCreateEipData(ctx context.Context, userCred mcclient.TokenCredential, input *api.SElasticipCreateInput) error {
|
||||
if err := self.ValidateEipChargeType(input.ChargeType); err != nil {
|
||||
return err
|
||||
@@ -986,20 +940,21 @@ func (self *SKVMRegionDriver) ValidateCreateEipData(ctx context.Context, userCre
|
||||
if err := db.FetchModelObjects(models.NetworkManager, q, &nets); err != nil {
|
||||
return err
|
||||
}
|
||||
eipNets := make([]eipNetwork, 0)
|
||||
eipNets := make([]models.SEipNetwork, 0)
|
||||
for i := range nets {
|
||||
net := &nets[i]
|
||||
cnt, _ := net.GetFreeAddressCount()
|
||||
if cnt > 0 {
|
||||
eipNets = append(eipNets, eipNetwork{net: net, freeCnt: cnt, owner: userCred})
|
||||
eipNets = append(eipNets, models.NewEipNetwork(net, userCred, userCred, cnt))
|
||||
}
|
||||
}
|
||||
if len(eipNets) == 0 {
|
||||
return httperrors.NewNotFoundError("no available eip network")
|
||||
}
|
||||
// prefer networks with identical project, domain, more free address, Id
|
||||
sort.Sort(eipNetworks(eipNets))
|
||||
network = eipNets[0].net
|
||||
sort.Sort(models.SEipNetworks(eipNets))
|
||||
log.Debugf("eipnets: %s", jsonutils.Marshal(eipNets))
|
||||
network = eipNets[0].GetNetwork()
|
||||
input.NetworkId = network.Id
|
||||
}
|
||||
if network.ServerType != api.NETWORK_TYPE_EIP {
|
||||
|
||||
Reference in New Issue
Block a user