Merge pull request #1407 from ioito/hotfix/qx-private-cloud-eip

private cloud filter eip by zone
This commit is contained in:
yunion-ci-robot
2019-06-27 17:31:50 +08:00
committed by GitHub
9 changed files with 135 additions and 20 deletions
+4 -2
View File
@@ -24,9 +24,11 @@ import (
func init() {
type ElasticipListOptions struct {
Region string `help:"Show servers in cloudregion"`
Region string `help:"List eips in cloudregion"`
Usable *bool `help:"List all zones that is usable"`
Usable *bool `help:"List all zones that is usable"`
UsableEipForAssociateType string `help:"With associate id filter which eip can associate"`
UsableEipForAssociateId string `help:"With associate type filter which eip can associate"`
options.BaseListOptions
}
+1
View File
@@ -23,6 +23,7 @@ get:
- $ref: '../parameters/instance.yaml#/hypervisor'
- $ref: '../parameters/instance.yaml#/secgroup'
- $ref: '../parameters/instance.yaml#/disk'
- $ref: '../parameters/instance.yaml#/usable_server_for_eip'
responses:
200:
description: 实例列表信息
+5
View File
@@ -60,3 +60,8 @@ order_by_host:
type: string
enum: [desc, asc]
description: 根据宿主机名称排序
usable_server_for_eip:
name: usable_server_for_eip
in: query
type: string
description: 过滤此EIP可绑定的server列表(实例和弹性IP属于同一个账号同一个区域,若是私有云则弹性IP和实例需要在同一个可用区)
+4
View File
@@ -38,3 +38,7 @@ const (
EIP_CHARGE_TYPE_BY_BANDWIDTH = "bandwidth"
EIP_CHARGE_TYPE_DEFAULT = EIP_CHARGE_TYPE_BY_TRAFFIC
)
var (
EIP_ASSOCIATE_VALID_TYPES = []string{EIP_ASSOCIATE_TYPE_SERVER, EIP_ASSOCIATE_TYPE_NAT_GATEWAY}
)
+4 -1
View File
@@ -153,9 +153,12 @@ var PUBLIC_CLOUD_HYPERVISORS = []string{
HYPERVISOR_AZURE,
HYPERVISOR_QCLOUD,
HYPERVISOR_HUAWEI,
HYPERVISOR_OPENSTACK,
HYPERVISOR_UCLOUD,
}
var PRIVATE_CLOUD_HYPERVISORS = []string{
HYPERVISOR_ZSTACK,
HYPERVISOR_OPENSTACK,
}
// var HYPERVISORS = []string{HYPERVISOR_ALIYUN}
+59
View File
@@ -122,6 +122,38 @@ func (manager *SElasticipManager) ListItemFilter(ctx context.Context, q *sqlchem
q = q.Equals("cloudregion_id", regionObj.GetId())
}
associateType, _ := query.GetString("usable_eip_for_associate_type")
associateId, _ := query.GetString("usable_eip_for_associate_id")
if len(associateType) > 0 && len(associateId) > 0 {
switch associateType {
case api.EIP_ASSOCIATE_TYPE_SERVER:
serverObj, err := GuestManager.FetchByIdOrName(userCred, associateId)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError("server %s not found", regionFilter)
}
return nil, httperrors.NewGeneralError(err)
}
guest := serverObj.(*SGuest)
if utils.IsInStringArray(guest.Hypervisor, api.PRIVATE_CLOUD_HYPERVISORS) {
zone := guest.getZone()
networks := NetworkManager.Query().SubQuery()
wires := WireManager.Query().SubQuery()
sq := networks.Query(networks.Field("id")).Join(wires, sqlchemy.Equals(wires.Field("id"), networks.Field("wire_id"))).
Filter(sqlchemy.Equals(wires.Field("zone_id"), zone.Id)).SubQuery()
q = q.Filter(sqlchemy.In(q.Field("network_id"), sq))
} else {
region := guest.getRegion()
q = q.Equals("cloudregion_id", region.Id)
}
managerId := guest.GetHost().ManagerId
q = q.Equals("manager_id", managerId)
default:
return nil, httperrors.NewInputParameterError("Not support associate type %s, only support %s", associateType, api.EIP_ASSOCIATE_VALID_TYPES)
}
}
/*accountStr := jsonutils.GetAnyString(query, []string{"account", "account_id", "cloudaccount", "cloudaccount_id"})
if len(accountStr) > 0 {
account, err := CloudaccountManager.FetchByIdOrName(nil, accountStr)
@@ -169,6 +201,25 @@ func (self *SElasticip) GetRegion() *SCloudregion {
return CloudregionManager.FetchRegionById(self.CloudregionId)
}
func (self *SElasticip) GetNetwork() (*SNetwork, error) {
network, err := NetworkManager.FetchById(self.NetworkId)
if err != nil {
return nil, err
}
return network.(*SNetwork), nil
}
func (self *SElasticip) GetZone() *SZone {
if len(self.NetworkId) == 0 {
return nil
}
network, err := self.GetNetwork()
if err != nil {
return nil
}
return network.getZone()
}
func (self *SElasticip) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
desc := self.SVirtualResourceBase.GetShortDesc(ctx)
@@ -750,6 +801,14 @@ func (self *SElasticip) PerformAssociate(ctx context.Context, userCred mcclient.
return nil, httperrors.NewInputParameterError("eip and server are not in the same region")
}
eipZone := self.GetZone()
if eipZone != nil {
serverZone := server.getZone()
if serverZone.Id != eipZone.Id {
return nil, httperrors.NewInputParameterError("eip and server are not in the same zone")
}
}
srvHost := server.GetHost()
if srvHost == nil {
return nil, httperrors.NewInputParameterError("server host is not found???")
+8
View File
@@ -2440,6 +2440,14 @@ func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.T
return nil, httperrors.NewInputParameterError("cannot associate eip and instance in different region")
}
eipZone := eip.GetZone()
if eipZone != nil {
insZone := self.getZone()
if eipZone.Id != insZone.Id {
return nil, httperrors.NewInputParameterError("cannot associate eip and instance in different zone")
}
}
host := self.GetHost()
if host == nil {
return nil, httperrors.NewInputParameterError("server host is not found???")
+32
View File
@@ -378,6 +378,38 @@ func (manager *SGuestManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQ
}
}
usableServerForEipFilter, _ := queryDict.GetString("usable_server_for_eip")
if len(usableServerForEipFilter) > 0 {
eipObj, err := ElasticipManager.FetchByIdOrName(userCred, usableServerForEipFilter)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError("eip %s not found", usableServerForEipFilter)
}
return nil, httperrors.NewGeneralError(err)
}
eip := eipObj.(*SElasticip)
hostTable := HostManager.Query().SubQuery()
zoneTable := ZoneManager.Query().SubQuery()
hostQ := hostTable.Query(hostTable.Field("id")).Join(zoneTable,
sqlchemy.Equals(zoneTable.Field("id"), hostTable.Field("zone_id"))).Equals("manager_id", eip.ManagerId)
if len(eip.NetworkId) > 0 {
network, err := eip.GetNetwork()
if err != nil {
return nil, err
}
zone := network.getZone()
sq := hostQ.Filter(sqlchemy.Equals(zoneTable.Field("id"), zone.GetId())).SubQuery()
q = q.In("host_id", sq)
} else {
region := eip.GetRegion()
regionTable := CloudregionManager.Query().SubQuery()
sq := hostQ.Join(regionTable, sqlchemy.Equals(zoneTable.Field("cloudregion_id"), regionTable.Field("id"))).
Filter(sqlchemy.Equals(regionTable.Field("id"), region.GetId())).SubQuery()
q = q.In("host_id", sq)
}
}
zoneFilter, _ := queryDict.GetString("zone")
if len(zoneFilter) > 0 {
zone, _ := ZoneManager.FetchByIdOrName(nil, zoneFilter)
+18 -17
View File
@@ -30,23 +30,24 @@ import (
)
type ServerListOptions struct {
Zone string `help:"Zone ID or Name"`
Wire string `help:"Wire ID or Name"`
Network string `help:"Network ID or Name"`
Disk string `help:"Disk ID or Name"`
Host string `help:"Host ID or Name"`
Baremetal *bool `help:"Show baremetal servers"`
Gpu *bool `help:"Show gpu servers"`
Secgroup string `help:"Secgroup ID or Name"`
AdminSecgroup string `help:"AdminSecgroup ID or Name"`
Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun|azure|aws|huawei|ucloud|zstack"`
Region string `help:"Show servers in cloudregion"`
WithEip *bool `help:"Show Servers with EIP"`
WithoutEip *bool `help:"Show Servers without EIP"`
OsType string `help:"OS Type" choices:"linux|windows|vmware"`
OrderByDisk string `help:"Order by disk size" choices:"asc|desc"`
OrderByHost string `help:"Order by host name" choices:"asc|desc"`
Vpc string `help:"Vpc id or name"`
Zone string `help:"Zone ID or Name"`
Wire string `help:"Wire ID or Name"`
Network string `help:"Network ID or Name"`
Disk string `help:"Disk ID or Name"`
Host string `help:"Host ID or Name"`
Baremetal *bool `help:"Show baremetal servers"`
Gpu *bool `help:"Show gpu servers"`
Secgroup string `help:"Secgroup ID or Name"`
AdminSecgroup string `help:"AdminSecgroup ID or Name"`
Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun|azure|aws|huawei|ucloud|zstack"`
Region string `help:"Show servers in cloudregion"`
WithEip *bool `help:"Show Servers with EIP"`
WithoutEip *bool `help:"Show Servers without EIP"`
OsType string `help:"OS Type" choices:"linux|windows|vmware"`
OrderByDisk string `help:"Order by disk size" choices:"asc|desc"`
OrderByHost string `help:"Order by host name" choices:"asc|desc"`
Vpc string `help:"Vpc id or name"`
UsableServerForEip string `help:"Eip id or name"`
ResourceType string `help:"Resource type" choices:"shared|prepaid|dedicated"`