diff --git a/pkg/util/huawei/client/client.go b/pkg/util/huawei/client/client.go index d5a02d63bc..6513db8d6a 100644 --- a/pkg/util/huawei/client/client.go +++ b/pkg/util/huawei/client/client.go @@ -58,6 +58,9 @@ type Client struct { Vpcs *modules.SVpcManager Zones *modules.SZoneManager VpcRoutes *modules.SVpcRouteManager + SNatRules *modules.SNatSRuleManager + DNatRules *modules.SNatDRuleManager + NatGateways *modules.SNatGatewayManager } func (self *Client) Init() error { @@ -120,6 +123,9 @@ func (self *Client) initManagers() { self.Port = modules.NewPortManager(self.regionId, self.projectId, self.signer, self.debug) self.Flavors = modules.NewFlavorManager(self.regionId, self.projectId, self.signer, self.debug) self.VpcRoutes = modules.NewVpcRouteManager(self.regionId, self.projectId, self.signer, self.debug) + self.SNatRules = modules.NewNatSManager(self.regionId, self.projectId, self.signer, self.debug) + self.DNatRules = modules.NewNatDManager(self.regionId, self.projectId, self.signer, self.debug) + self.NatGateways = modules.NewNatGatewayManager(self.regionId, self.projectId, self.signer, self.debug) } self.init = true diff --git a/pkg/util/huawei/client/modules/manager_resource.go b/pkg/util/huawei/client/modules/manager_resource.go index 3b386750a9..9ab4f4664e 100644 --- a/pkg/util/huawei/client/modules/manager_resource.go +++ b/pkg/util/huawei/client/modules/manager_resource.go @@ -45,6 +45,7 @@ const ( ServiceNameVPC ServiceNameType = "vpc" // 虚拟私有云 VPC ServiceNameELB ServiceNameType = "elb" // 弹性负载均衡 ELB ServiceNameBSS ServiceNameType = "bss" // 合作伙伴运营能力 + ServiceNameNAT ServiceNameType = "nat" // Nat网关 NAT ) diff --git a/pkg/util/huawei/client/modules/mod_dnat_rules.go b/pkg/util/huawei/client/modules/mod_dnat_rules.go new file mode 100644 index 0000000000..dc6b1014a3 --- /dev/null +++ b/pkg/util/huawei/client/modules/mod_dnat_rules.go @@ -0,0 +1,37 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package modules + +import ( + "yunion.io/x/onecloud/pkg/util/huawei/client/auth" +) + +type SNatDRuleManager struct { + SResourceManager +} + +func NewNatDManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatDRuleManager { + return &SNatDRuleManager{SResourceManager: SResourceManager{ + SBaseManager: NewBaseManager(signer, debug), + ServiceName: ServiceNameNAT, + Region: regionId, + ProjectId: "", + version: "v2.0", + Keyword: "dnat_rule", + KeywordPlural: "dnat_rules", + + ResourceKeyword: "dnat_rules", + }} +} diff --git a/pkg/util/huawei/client/modules/mod_natgateway.go b/pkg/util/huawei/client/modules/mod_natgateway.go new file mode 100644 index 0000000000..2cf9c35999 --- /dev/null +++ b/pkg/util/huawei/client/modules/mod_natgateway.go @@ -0,0 +1,37 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package modules + +import ( + "yunion.io/x/onecloud/pkg/util/huawei/client/auth" +) + +type SNatGatewayManager struct { + SResourceManager +} + +func NewNatGatewayManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatGatewayManager { + return &SNatGatewayManager{SResourceManager: SResourceManager{ + SBaseManager: NewBaseManager(signer, debug), + ServiceName: ServiceNameNAT, + Region: regionId, + ProjectId: "", + version: "v2.0", + Keyword: "nat_gateway", + KeywordPlural: "nat_gateways", + + ResourceKeyword: "nat_gateways", + }} +} diff --git a/pkg/util/huawei/client/modules/mod_snat_rules.go b/pkg/util/huawei/client/modules/mod_snat_rules.go new file mode 100644 index 0000000000..567afc33ff --- /dev/null +++ b/pkg/util/huawei/client/modules/mod_snat_rules.go @@ -0,0 +1,37 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package modules + +import ( + "yunion.io/x/onecloud/pkg/util/huawei/client/auth" +) + +type SNatSRuleManager struct { + SResourceManager +} + +func NewNatSManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatSRuleManager { + return &SNatSRuleManager{SResourceManager: SResourceManager{ + SBaseManager: NewBaseManager(signer, debug), + ServiceName: ServiceNameNAT, + Region: regionId, + ProjectId: "", + version: "v2.0", + Keyword: "snat_rule", + KeywordPlural: "snat_rules", + + ResourceKeyword: "snat_rules", + }} +} diff --git a/pkg/util/huawei/eip.go b/pkg/util/huawei/eip.go index 85dd738343..ed2f4bf82d 100644 --- a/pkg/util/huawei/eip.go +++ b/pkg/util/huawei/eip.go @@ -33,17 +33,18 @@ const ( ) type Port struct { - ID string `json:"id"` - Name string `json:"name"` - Status string `json:"status"` - AdminStateUp string `json:"admin_state_up"` - DNSName string `json:"dns_name"` - MACAddress string `json:"mac_address"` - NetworkID string `json:"network_id"` - TenantID string `json:"tenant_id"` - DeviceID string `json:"device_id"` - DeviceOwner string `json:"device_owner"` - BindingVnicType string `json:"binding:vnic_type"` + ID string `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + AdminStateUp string `json:"admin_state_up"` + DNSName string `json:"dns_name"` + MACAddress string `json:"mac_address"` + NetworkID string `json:"network_id"` + TenantID string `json:"tenant_id"` + DeviceID string `json:"device_id"` + DeviceOwner string `json:"device_owner"` + BindingVnicType string `json:"binding:vnic_type"` + FixedIPs []FixedIP `json:"fixed_ips"` } type Bandwidth struct { diff --git a/pkg/util/huawei/natdtable.go b/pkg/util/huawei/natdtable.go new file mode 100644 index 0000000000..33478b971a --- /dev/null +++ b/pkg/util/huawei/natdtable.go @@ -0,0 +1,108 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package huawei + +import ( + "yunion.io/x/onecloud/pkg/multicloud" + "yunion.io/x/pkg/errors" +) + +type SNatDTableEntry struct { + multicloud.SResourceBase + gateway *SNatGateway + + ID string `json:"id"` + NatGatewayID string `json:"nat_gateway_id"` + Protocol string `json:"protocol"` + Status string `json:"status"` + ExternalIP string `json:"floating_ip_address"` + ExternalPort int `json:"external_service_port"` + InternalIP string `json:"private_ip"` + InternalPort int `json:"internal_service_port"` + PortID string `json:"port_id"` + AdminStateUp bool `json:"admin_state_up"` +} + +func (nat *SNatDTableEntry) GetId() string { + return nat.ID +} + +func (nat *SNatDTableEntry) GetName() string { + // No name so return id + return nat.GetId() +} + +func (nat *SNatDTableEntry) GetGlobalId() string { + return nat.GetId() +} + +func (nat *SNatDTableEntry) GetStatus() string { + return NatResouceStatusTransfer(nat.Status) +} + +func (nat *SNatDTableEntry) GetIpProtocol() string { + return nat.Protocol +} + +func (nat *SNatDTableEntry) GetExternalIp() string { + return nat.ExternalIP +} + +func (nat *SNatDTableEntry) GetExternalPort() int { + return nat.ExternalPort +} + +func (nat *SNatDTableEntry) GetInternalIp() string { + return nat.InternalIP +} + +func (nat *SNatDTableEntry) GetInternalPort() int { + return nat.InternalPort +} + +// getSNatEntries return all snat rules of gateway +func (gateway *SNatGateway) getDNatEntries() ([]SNatDTableEntry, error) { + ret, err := gateway.region.GetDNatTable(gateway.GetId()) + if err != nil { + return nil, err + } + for i := range ret { + ret[i].gateway = gateway + } + return ret, nil +} + +func (region *SRegion) GetDNatTable(natGatewayID string) ([]SNatDTableEntry, error) { + queuies := map[string]string{ + "nat_gateway_id": natGatewayID, + } + dNatSTableEntries := make([]SNatDTableEntry, 0, 2) + // can't make true that restapi support marker para in Huawei Cloud + err := doListAllWithMarker(region.ecsClient.DNatRules.List, queuies, &dNatSTableEntries) + if err != nil { + return nil, errors.Wrapf(err, `get dnat rule of gateway %q`, natGatewayID) + } + for i := range dNatSTableEntries { + nat := &dNatSTableEntries[i] + if len(nat.InternalIP) == 0 { + port, err := region.GetPort(nat.PortID) + if err != nil { + return nil, errors.Wrapf(err, `get port info for transfer to ip of port_id %q error`, nat.PortID) + } + nat.InternalIP = port.FixedIPs[0].IPAddress + } + } + return dNatSTableEntries, nil +} diff --git a/pkg/util/huawei/natgateway.go b/pkg/util/huawei/natgateway.go new file mode 100644 index 0000000000..b98636783c --- /dev/null +++ b/pkg/util/huawei/natgateway.go @@ -0,0 +1,199 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package huawei + +import ( + "time" + billing_api "yunion.io/x/onecloud/pkg/apis/billing" + api "yunion.io/x/onecloud/pkg/apis/compute" + "yunion.io/x/onecloud/pkg/cloudprovider" + "yunion.io/x/onecloud/pkg/multicloud" + "yunion.io/x/pkg/errors" +) + +type SNatGateway struct { + multicloud.SNatGatewayBase + region *SRegion + + natDTable []cloudprovider.ICloudNatDTable + natSTable []cloudprovider.ICloudNatSTable + + ID string + Name string + Description string + Spec string + Status string + CreatedTime string `json:"created_at"` +} + +func (nat *SNatGateway) GetId() string { + return nat.ID +} + +func (nat *SNatGateway) GetName() string { + return nat.Name +} + +func (nat *SNatGateway) GetGlobalId() string { + return nat.GetId() +} + +func (nat *SNatGateway) GetStatus() string { + return NatResouceStatusTransfer(nat.Status) +} + +func (nat *SNatGateway) GetNatSpec() string { + switch nat.Spec { + case "1": + return "small" + case "2": + return "middle" + case "3": + return "large" + case "4": + return "xlarge" + } + // can't arrive + return "" +} + +func (nat *SNatGateway) GetDescription() string { + return nat.Description +} + +func (nat *SNatGateway) GetBillingType() string { + // Up to 2019.07.17, only support post pay + return billing_api.BILLING_TYPE_POSTPAID +} + +func (nat *SNatGateway) GetCreatedAt() time.Time { + t, _ := time.Parse("2006-01-02 15:04:05.000000", nat.CreatedTime) + return t +} + +func (nat *SNatGateway) GetExpiredAt() time.Time { + // no support for expired time + return time.Time{} +} + +func (nat *SNatGateway) GetIEips() ([]cloudprovider.ICloudEIP, error) { + // Get all IEips of nat's region, which IpAddr is in the ExternalIPs of nat's Nat Rules. + IEips, err := nat.region.GetIEips() + if err != nil { + return nil, errors.Wrapf(err, `get all Eips of region %q error`, nat.region.GetId()) + } + dNatTables, err := nat.GetINatDTables() + if err != nil { + return nil, errors.Wrapf(err, `get all DNatTable of gateway %q error`, nat.GetId()) + } + sNatTables, err := nat.GetINatSTables() + if err != nil { + return nil, errors.Wrapf(err, `get all SNatTable of gateway %q error`, nat.GetId()) + } + + // Get natIPSet of nat rules + natIPSet := make(map[string]struct{}) + for _, snat := range sNatTables { + natIPSet[snat.GetIP()] = struct{}{} + } + for _, dnat := range dNatTables { + natIPSet[dnat.GetExternalIp()] = struct{}{} + } + + // Add Eip whose GetIpAddr() in natIPSet to ret + ret := make([]cloudprovider.ICloudEIP, 0, 2) + for i := range IEips { + if _, ok := natIPSet[IEips[i].GetIpAddr()]; ok { + ret = append(ret, IEips[i]) + } + } + return ret, nil +} + +func (nat *SNatGateway) GetINatDTables() ([]cloudprovider.ICloudNatDTable, error) { + if nat.natDTable != nil { + return nat.natDTable, nil + } + dNatTable, err := nat.getDNatEntries() + if err != nil { + return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, nat.GetId()) + } + ret := make([]cloudprovider.ICloudNatDTable, len(dNatTable)) + for i := range dNatTable { + ret[i] = &dNatTable[i] + } + return ret, nil +} + +func (nat *SNatGateway) GetINatSTables() ([]cloudprovider.ICloudNatSTable, error) { + if nat.natSTable != nil { + return nat.natSTable, nil + } + sNatTable, err := nat.getSNatEntries() + if err != nil { + return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, nat.GetId()) + } + ret := make([]cloudprovider.ICloudNatSTable, len(sNatTable)) + for i := range sNatTable { + ret[i] = &sNatTable[i] + } + return ret, nil +} + +func (region *SRegion) GetNatGateway(natGatewayID string) ([]SNatGateway, error) { + queues := make(map[string]string) + if natGatewayID != "" { + queues["id"] = natGatewayID + } + natGateways := make([]SNatGateway, 0, 2) + err := doListAllWithMarker(region.ecsClient.NatGateways.List, queues, &natGateways) + if err != nil { + return nil, errors.Wrapf(err, "get nat gateways error") + } + for i := range natGateways { + natGateways[i].region = region + } + return natGateways, nil +} + +func (region *SRegion) GetNatGateways(vpcID string) ([]SNatGateway, error) { + queues := map[string]string{ + "router_id": vpcID, + } + natGateways := make([]SNatGateway, 0, 2) + err := doListAllWithMarker(region.ecsClient.NatGateways.List, queues, &natGateways) + if err != nil { + return nil, errors.Wrapf(err, "get nat gateways error by vpcid") + } + for i := range natGateways { + natGateways[i].region = region + } + return natGateways, nil +} + +func NatResouceStatusTransfer(status string) string { + // In Huawei Cloud, there are isx resource status of Nat, "ACTIVE", "PENDING_CREATE", + // "PENDING_UPDATE", "PENDING_DELETE", "EIP_FREEZED", "INACTIVE". + switch status { + case "ACTIVE": + return api.NAT_STAUTS_AVAILABLE + case "PENDING_CREATE": + return api.NAT_STATUS_ALLOCATE + case "PENDING_UPDATE", "PENDING_DELETE": + return api.NAT_STATUS_DEPLOYING + default: + return api.NAT_STATUS_UNKNOWN + } +} diff --git a/pkg/util/huawei/natstable.go b/pkg/util/huawei/natstable.go new file mode 100644 index 0000000000..9b0893cce0 --- /dev/null +++ b/pkg/util/huawei/natstable.go @@ -0,0 +1,98 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package huawei + +import ( + "yunion.io/x/onecloud/pkg/multicloud" + "yunion.io/x/pkg/errors" +) + +type SNatSTableEntry struct { + multicloud.SResourceBase + gateway *SNatGateway + + ID string `json:"id"` + NatGatewayID string `json:"nat_gateway_id"` + NetworkID string `json:"network_id"` + SourceCIDR string `json:"cidr"` + Status string `json:"status"` + SNatIP string `json:"floating_ip_address"` + AdminStateUp bool `json:"admin_state_up"` +} + +func (nat *SNatSTableEntry) GetId() string { + return nat.ID +} + +func (nat *SNatSTableEntry) GetName() string { + // Snat rule has no name in Huawei Cloud, so return ID + return nat.GetId() +} + +func (nat *SNatSTableEntry) GetGlobalId() string { + return nat.GetId() +} + +func (nat *SNatSTableEntry) GetStatus() string { + return NatResouceStatusTransfer(nat.Status) +} + +func (nat *SNatSTableEntry) GetIP() string { + return nat.SNatIP +} + +func (nat *SNatSTableEntry) GetSourceCIDR() string { + return nat.SourceCIDR +} + +func (nat *SNatSTableEntry) GetNetworkId() string { + return nat.NetworkID +} + +// getSNatEntries return all snat rules of gateway +func (gateway *SNatGateway) getSNatEntries() ([]SNatSTableEntry, error) { + ret, err := gateway.region.GetSNatTable(gateway.GetId()) + if err != nil { + return nil, err + } + for i := range ret { + ret[i].gateway = gateway + } + return ret, nil +} + +func (region *SRegion) GetSNatTable(natGatewayID string) ([]SNatSTableEntry, error) { + queuies := map[string]string{ + "nat_gateway_id": natGatewayID, + } + sNatSTableEntris := make([]SNatSTableEntry, 0, 2) + err := doListAllWithMarker(region.ecsClient.SNatRules.List, queuies, &sNatSTableEntris) + if err != nil { + return nil, errors.Wrapf(err, `get snat rule of gateway %q`, natGatewayID) + } + for i := range sNatSTableEntris { + nat := &sNatSTableEntris[i] + if len(nat.SourceCIDR) != 0 { + continue + } + subnet := SNetwork{} + err := DoGet(region.ecsClient.Subnets.Get, nat.NetworkID, map[string]string{}, &subnet) + if err != nil { + return nil, errors.Wrapf(err, `get cidr of subnet %q`, nat.NetworkID) + } + nat.SourceCIDR = subnet.CIDR + } + return sNatSTableEntris, nil +} diff --git a/pkg/util/huawei/shell/natdtable.go b/pkg/util/huawei/shell/natdtable.go new file mode 100644 index 0000000000..4803d91f60 --- /dev/null +++ b/pkg/util/huawei/shell/natdtable.go @@ -0,0 +1,34 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shell + +import ( + "yunion.io/x/onecloud/pkg/util/huawei" + "yunion.io/x/onecloud/pkg/util/shellutils" +) + +func init() { + type DNatTableOptions struct { + NatGatewayID string `help:"Nat Gateway ID" positional:"true"` + } + shellutils.R(&DNatTableOptions{}, "dnat-table-list", "list dnat table", func(region *huawei.SRegion, args *DNatTableOptions) error { + DNatTable, err := region.GetDNatTable(args.NatGatewayID) + if err != nil { + return err + } + printList(DNatTable, 0, 0, 0, nil) + return nil + }) +} diff --git a/pkg/util/huawei/shell/natgateway.go b/pkg/util/huawei/shell/natgateway.go new file mode 100644 index 0000000000..2a0fbd06c7 --- /dev/null +++ b/pkg/util/huawei/shell/natgateway.go @@ -0,0 +1,34 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shell + +import ( + "yunion.io/x/onecloud/pkg/util/huawei" + "yunion.io/x/onecloud/pkg/util/shellutils" +) + +func init() { + type NatGatewayOptions struct { + NatGatewayID string `help:"Nat Gateway ID"` + } + shellutils.R(&NatGatewayOptions{}, "nat-gateway-list", "list nat gateway", func(region *huawei.SRegion, args *NatGatewayOptions) error { + natGateways, err := region.GetNatGateway(args.NatGatewayID) + if err != nil { + return err + } + printList(natGateways, 0, 0, 0, nil) + return nil + }) +} diff --git a/pkg/util/huawei/shell/natstable.go b/pkg/util/huawei/shell/natstable.go new file mode 100644 index 0000000000..dcb1f57ce7 --- /dev/null +++ b/pkg/util/huawei/shell/natstable.go @@ -0,0 +1,34 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package shell + +import ( + "yunion.io/x/onecloud/pkg/util/huawei" + "yunion.io/x/onecloud/pkg/util/shellutils" +) + +func init() { + type SNatTableOptions struct { + NatGatewayID string `help:"Nat Gateway ID" positional:"true"` + } + shellutils.R(&SNatTableOptions{}, "snat-table-list", "list snat table", func(region *huawei.SRegion, args *SNatTableOptions) error { + sNatTable, err := region.GetSNatTable(args.NatGatewayID) + if err != nil { + return err + } + printList(sNatTable, 0, 0, 0, nil) + return nil + }) +} diff --git a/pkg/util/huawei/vpc.go b/pkg/util/huawei/vpc.go index 3b9c576f8a..962a5f2bdd 100644 --- a/pkg/util/huawei/vpc.go +++ b/pkg/util/huawei/vpc.go @@ -16,8 +16,8 @@ package huawei import ( "strings" - "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/errors" "yunion.io/x/jsonutils" api "yunion.io/x/onecloud/pkg/apis/compute" @@ -205,6 +205,18 @@ func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) return nil, cloudprovider.ErrNotFound } +func (self *SVpc) GetINatGateways() ([]cloudprovider.ICloudNatGateway, error) { + nats, err := self.region.GetNatGateways(self.GetId()) + if err != nil { + return nil, err + } + ret := make([]cloudprovider.ICloudNatGateway, len(nats)) + for i := 0; i < len(nats); i++ { + ret[i] = &nats[i] + } + return ret, nil +} + func (self *SRegion) getVpc(vpcId string) (*SVpc, error) { vpc := SVpc{} err := DoGet(self.ecsClient.Vpcs.Get, vpcId, nil, &vpc)