diff --git a/pkg/apis/compute/guests.go b/pkg/apis/compute/guests.go index fe6841836a..a1d97a9bbf 100644 --- a/pkg/apis/compute/guests.go +++ b/pkg/apis/compute/guests.go @@ -54,8 +54,10 @@ type ServerListInput struct { Hypervisor []string `json:"hypervisor"` // 列出绑定了弹性IP(EIP)的主机 WithEip *bool `json:"with_eip"` - // 列出未绑定弹性IP(EIO)的主机 + // 列出未绑定弹性IP(EIP)的主机 WithoutEip *bool `json:"without_eip"` + // 列出可绑定弹性IP的主机 + EipAssociable *bool `json:"eip_associable"` // 列出操作系统为指定值的主机 // enum: linux,windows,vmware OsType []string `json:"os_type"` diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 23a4015dce..11997d2124 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -401,7 +401,7 @@ func (manager *SGuestManager) ListItemFilter( } withEip := (query.WithEip != nil && *query.WithEip) - withoutEip := (query.WithoutEip != nil && *query.WithoutEip) + withoutEip := (query.WithoutEip != nil && *query.WithoutEip) || (query.EipAssociable != nil && *query.EipAssociable) if withEip || withoutEip { eips := ElasticipManager.Query().SubQuery() sq := eips.Query(eips.Field("associate_id")).Equals("associate_type", api.EIP_ASSOCIATE_TYPE_SERVER) @@ -413,6 +413,23 @@ func (manager *SGuestManager) ListItemFilter( q = q.NotIn("id", sq) } } + + if query.EipAssociable != nil { + sq1 := NetworkManager.Query("id") + sq2 := WireManager.Query().SubQuery() + sq3 := VpcManager.Query().SubQuery() + sq1 = sq1.Join(sq2, sqlchemy.Equals(sq1.Field("wire_id"), sq2.Field("id"))) + sq1 = sq1.Join(sq3, sqlchemy.Equals(sq2.Field("vpc_id"), sq3.Field("id"))) + cond1 := []string{api.VPC_EXTERNAL_ACCESS_MODE_EIP, api.VPC_EXTERNAL_ACCESS_MODE_EIP_DISTGW} + if *query.EipAssociable { + sq1 = sq1.Filter(sqlchemy.In(sq3.Field("external_access_mode"), cond1)) + } else { + sq1 = sq1.Filter(sqlchemy.NotIn(sq3.Field("external_access_mode"), cond1)) + } + sq := GuestnetworkManager.Query("guest_id").In("network_id", sq1) + q = q.In("id", sq) + } + if len(query.ServerType) > 0 { var trueVal, falseVal = true, false switch query.ServerType { diff --git a/pkg/mcclient/options/servers.go b/pkg/mcclient/options/servers.go index f679203e1a..820bfb981a 100644 --- a/pkg/mcclient/options/servers.go +++ b/pkg/mcclient/options/servers.go @@ -50,6 +50,7 @@ type ServerListOptions struct { Vpc string `help:"Vpc id or name"` UsableServerForEip string `help:"Eip id or name"` WithoutUserMeta *bool `help:"Show Servers without user metadata"` + EipAssociable *bool `help:"Show Servers can associate with eip"` Group string `help:"Instance Group ID or Name"` HostSn string `help:"Host SN"` IpAddr string `help:"Fileter by ip"`