From 666def70cc9b13845ba47cdca2105bbe1a7bcfb2 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Jul 2019 20:21:30 +0800 Subject: [PATCH 1/2] huawei nat list finish without testing --- pkg/util/huawei/client/client.go | 6 + .../huawei/client/modules/mod_dnap_rules.go | 37 ++++ .../huawei/client/modules/mod_natgateway.go | 37 ++++ .../huawei/client/modules/mod_snap_rules.go | 37 ++++ pkg/util/huawei/natdtable.go | 102 ++++++++++ pkg/util/huawei/natgateway.go | 177 ++++++++++++++++++ pkg/util/huawei/natgateway_test.go | 46 +++++ pkg/util/huawei/natstable.go | 91 +++++++++ pkg/util/huawei/shell/natdtable.go | 1 + pkg/util/huawei/shell/natgateway.go | 1 + pkg/util/huawei/shell/natstable.go | 1 + 11 files changed, 536 insertions(+) create mode 100644 pkg/util/huawei/client/modules/mod_dnap_rules.go create mode 100644 pkg/util/huawei/client/modules/mod_natgateway.go create mode 100644 pkg/util/huawei/client/modules/mod_snap_rules.go create mode 100644 pkg/util/huawei/natdtable.go create mode 100644 pkg/util/huawei/natgateway.go create mode 100644 pkg/util/huawei/natgateway_test.go create mode 100644 pkg/util/huawei/natstable.go create mode 100644 pkg/util/huawei/shell/natdtable.go create mode 100644 pkg/util/huawei/shell/natgateway.go create mode 100644 pkg/util/huawei/shell/natstable.go 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/mod_dnap_rules.go b/pkg/util/huawei/client/modules/mod_dnap_rules.go new file mode 100644 index 0000000000..d284b4305d --- /dev/null +++ b/pkg/util/huawei/client/modules/mod_dnap_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: ServiceNameVPC, + 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..a827b46f17 --- /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: ServiceNameVPC, + Region: regionId, + ProjectId: "", + version: "v2.0", + Keyword: "nat_gateway", + KeywordPlural: "nat_gateways", + + ResourceKeyword: "nat_gateways", + }} +} diff --git a/pkg/util/huawei/client/modules/mod_snap_rules.go b/pkg/util/huawei/client/modules/mod_snap_rules.go new file mode 100644 index 0000000000..8800d0f178 --- /dev/null +++ b/pkg/util/huawei/client/modules/mod_snap_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: ServiceNameVPC, + Region: regionId, + ProjectId: "", + version: "v2.0", + Keyword: "snat_rule", + KeywordPlural: "snat_rules", + + ResourceKeyword: "snat_rules", + }} +} diff --git a/pkg/util/huawei/natdtable.go b/pkg/util/huawei/natdtable.go new file mode 100644 index 0000000000..9a97c1888d --- /dev/null +++ b/pkg/util/huawei/natdtable.go @@ -0,0 +1,102 @@ +// 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"` +} + +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) { + queuies := map[string]string{ + "nat_gateway_id": gateway.GetId(), + } + dNatSTableEntris := make([]SNatDTableEntry, 0, 2) + // can't make true that restapi support marker para in Huawei Cloud + err := doListAllWithMarker(gateway.region.ecsClient.DNatRules.List, queuies, &dNatSTableEntris) + if err != nil { + return nil, errors.Wrapf(err, `get dnat rule of gateway %q`, gateway.GetId()) + } + + for i := range dNatSTableEntris { + dNatSTableEntris[i].gateway = gateway + } + return dNatSTableEntris, nil +} + +func (region *SRegion) GetDNatTable(natGatewayID string) ([]SNatDTableEntry, error) { + queuies := map[string]string{ + "nat_gateway_id": natGatewayID, + } + dNatSTableEntris := make([]SNatDTableEntry, 0, 2) + // can't make true that restapi support marker para in Huawei Cloud + err := doListAllWithMarker(region.ecsClient.DNatRules.List, queuies, &dNatSTableEntris) + if err != nil { + return nil, errors.Wrapf(err, `get dnat rule of gateway %q`, natGatewayID) + } + return dNatSTableEntris, nil +} diff --git a/pkg/util/huawei/natgateway.go b/pkg/util/huawei/natgateway.go new file mode 100644 index 0000000000..4e2f408456 --- /dev/null +++ b/pkg/util/huawei/natgateway.go @@ -0,0 +1,177 @@ +// 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" + "yunion.io/x/pkg/errors" + + 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" +) + +type SNatGateway struct { + multicloud.SNatGatewayBase + region *SRegion + + natDTable []cloudprovider.ICloudNatDTable + natSTable []cloudprovider.ICloudNatSTable + + ID string + Name string + Description string + Spec string + Status string + CreatedTime time.Time `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) GetBillingType() string { + // Up to 2019.07.17, only support post pay + return billing_api.BILLING_TYPE_POSTPAID +} + +func (nat *SNatGateway) GetCreatedAt() time.Time { + return nat.CreatedTime +} + +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) { + queuies := make(map[string]string) + if natGatewayID != "" { + queuies["id"] = natGatewayID + } + natGateways := make([]SNatGateway, 0, 2) + err := doListAllWithMarker(region.ecsClient.NatGateways.List, queuies, &natGateways) + if err != nil { + return nil, errors.Wrapf(err, "get nat gateways error") + } + 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/natgateway_test.go b/pkg/util/huawei/natgateway_test.go new file mode 100644 index 0000000000..3771971da4 --- /dev/null +++ b/pkg/util/huawei/natgateway_test.go @@ -0,0 +1,46 @@ +// 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 ( + "testing" + "yunion.io/x/log" +) + +const ( + PROJECT_ID = "41f6bfe48d7f4455b7754f7c1b11ae34" + ACCESS_KEY = "BLFG27EGJARKKG9HRKGT" + SECRET = "9LzCQcE9JogwQM7t42JaFcFfmPQCuUBdjmXSDibw" +) + +var region *SRegion + +func TestMain(m *testing.M) { + huaweiClient, err := NewHuaweiClient("001", "huaweiZyTest", "", ACCESS_KEY, SECRET, PROJECT_ID, true) + if err != nil { + log.Fatalln(err) + } + regionTmp := huaweiClient.iregions[0] + region = regionTmp.(*SRegion) + m.Run() +} + +func TestSRegion_GetDNatTable(t *testing.T) { + +} + +func TestSregion_GetSNatTable(t *testing.T) { + +} diff --git a/pkg/util/huawei/natstable.go b/pkg/util/huawei/natstable.go new file mode 100644 index 0000000000..fb8b346ba1 --- /dev/null +++ b/pkg/util/huawei/natstable.go @@ -0,0 +1,91 @@ +// 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"` +} + +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) { + queuies := map[string]string{ + "nat_gateway_id": gateway.GetId(), + } + sNatSTableEntris := make([]SNatSTableEntry, 0, 2) + err := doListAllWithMarker(gateway.region.ecsClient.SNatRules.List, queuies, &sNatSTableEntris) + if err != nil { + return nil, errors.Wrapf(err, `get snat rule of gateway %q`, gateway.GetId()) + } + + for i := range sNatSTableEntris { + sNatSTableEntris[i].gateway = gateway + } + return sNatSTableEntris, 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) + } + + 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..b1f847e427 --- /dev/null +++ b/pkg/util/huawei/shell/natdtable.go @@ -0,0 +1 @@ +package shell diff --git a/pkg/util/huawei/shell/natgateway.go b/pkg/util/huawei/shell/natgateway.go new file mode 100644 index 0000000000..b1f847e427 --- /dev/null +++ b/pkg/util/huawei/shell/natgateway.go @@ -0,0 +1 @@ +package shell diff --git a/pkg/util/huawei/shell/natstable.go b/pkg/util/huawei/shell/natstable.go new file mode 100644 index 0000000000..b1f847e427 --- /dev/null +++ b/pkg/util/huawei/shell/natstable.go @@ -0,0 +1 @@ +package shell From 94c985922843b24b403750ee3e697175772a668c Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 18 Jul 2019 20:40:14 +0800 Subject: [PATCH 2/2] support sync and list natgateway, snat table and dnat table --- .../huawei/client/modules/manager_resource.go | 1 + .../{mod_dnap_rules.go => mod_dnat_rules.go} | 2 +- .../huawei/client/modules/mod_natgateway.go | 2 +- .../{mod_snap_rules.go => mod_snat_rules.go} | 2 +- pkg/util/huawei/eip.go | 23 +++++----- pkg/util/huawei/natdtable.go | 34 ++++++++------ pkg/util/huawei/natgateway.go | 36 ++++++++++++--- pkg/util/huawei/natgateway_test.go | 46 ------------------- pkg/util/huawei/natstable.go | 31 ++++++++----- pkg/util/huawei/shell/natdtable.go | 33 +++++++++++++ pkg/util/huawei/shell/natgateway.go | 33 +++++++++++++ pkg/util/huawei/shell/natstable.go | 33 +++++++++++++ pkg/util/huawei/vpc.go | 14 +++++- 13 files changed, 196 insertions(+), 94 deletions(-) rename pkg/util/huawei/client/modules/{mod_dnap_rules.go => mod_dnat_rules.go} (97%) rename pkg/util/huawei/client/modules/{mod_snap_rules.go => mod_snat_rules.go} (97%) delete mode 100644 pkg/util/huawei/natgateway_test.go 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_dnap_rules.go b/pkg/util/huawei/client/modules/mod_dnat_rules.go similarity index 97% rename from pkg/util/huawei/client/modules/mod_dnap_rules.go rename to pkg/util/huawei/client/modules/mod_dnat_rules.go index d284b4305d..dc6b1014a3 100644 --- a/pkg/util/huawei/client/modules/mod_dnap_rules.go +++ b/pkg/util/huawei/client/modules/mod_dnat_rules.go @@ -25,7 +25,7 @@ type SNatDRuleManager struct { func NewNatDManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatDRuleManager { return &SNatDRuleManager{SResourceManager: SResourceManager{ SBaseManager: NewBaseManager(signer, debug), - ServiceName: ServiceNameVPC, + ServiceName: ServiceNameNAT, Region: regionId, ProjectId: "", version: "v2.0", diff --git a/pkg/util/huawei/client/modules/mod_natgateway.go b/pkg/util/huawei/client/modules/mod_natgateway.go index a827b46f17..2cf9c35999 100644 --- a/pkg/util/huawei/client/modules/mod_natgateway.go +++ b/pkg/util/huawei/client/modules/mod_natgateway.go @@ -25,7 +25,7 @@ type SNatGatewayManager struct { func NewNatGatewayManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatGatewayManager { return &SNatGatewayManager{SResourceManager: SResourceManager{ SBaseManager: NewBaseManager(signer, debug), - ServiceName: ServiceNameVPC, + ServiceName: ServiceNameNAT, Region: regionId, ProjectId: "", version: "v2.0", diff --git a/pkg/util/huawei/client/modules/mod_snap_rules.go b/pkg/util/huawei/client/modules/mod_snat_rules.go similarity index 97% rename from pkg/util/huawei/client/modules/mod_snap_rules.go rename to pkg/util/huawei/client/modules/mod_snat_rules.go index 8800d0f178..567afc33ff 100644 --- a/pkg/util/huawei/client/modules/mod_snap_rules.go +++ b/pkg/util/huawei/client/modules/mod_snat_rules.go @@ -25,7 +25,7 @@ type SNatSRuleManager struct { func NewNatSManager(regionId string, projectId string, signer auth.Signer, debug bool) *SNatSRuleManager { return &SNatSRuleManager{SResourceManager: SResourceManager{ SBaseManager: NewBaseManager(signer, debug), - ServiceName: ServiceNameVPC, + ServiceName: ServiceNameNAT, Region: regionId, ProjectId: "", version: "v2.0", 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 index 9a97c1888d..33478b971a 100644 --- a/pkg/util/huawei/natdtable.go +++ b/pkg/util/huawei/natdtable.go @@ -31,6 +31,8 @@ type SNatDTableEntry struct { 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 { @@ -72,31 +74,35 @@ func (nat *SNatDTableEntry) GetInternalPort() int { // getSNatEntries return all snat rules of gateway func (gateway *SNatGateway) getDNatEntries() ([]SNatDTableEntry, error) { - queuies := map[string]string{ - "nat_gateway_id": gateway.GetId(), - } - dNatSTableEntris := make([]SNatDTableEntry, 0, 2) - // can't make true that restapi support marker para in Huawei Cloud - err := doListAllWithMarker(gateway.region.ecsClient.DNatRules.List, queuies, &dNatSTableEntris) + ret, err := gateway.region.GetDNatTable(gateway.GetId()) if err != nil { - return nil, errors.Wrapf(err, `get dnat rule of gateway %q`, gateway.GetId()) + return nil, err } - - for i := range dNatSTableEntris { - dNatSTableEntris[i].gateway = gateway + for i := range ret { + ret[i].gateway = gateway } - return dNatSTableEntris, nil + return ret, nil } func (region *SRegion) GetDNatTable(natGatewayID string) ([]SNatDTableEntry, error) { queuies := map[string]string{ "nat_gateway_id": natGatewayID, } - dNatSTableEntris := make([]SNatDTableEntry, 0, 2) + dNatSTableEntries := make([]SNatDTableEntry, 0, 2) // can't make true that restapi support marker para in Huawei Cloud - err := doListAllWithMarker(region.ecsClient.DNatRules.List, queuies, &dNatSTableEntris) + err := doListAllWithMarker(region.ecsClient.DNatRules.List, queuies, &dNatSTableEntries) if err != nil { return nil, errors.Wrapf(err, `get dnat rule of gateway %q`, natGatewayID) } - return dNatSTableEntris, nil + 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 index 4e2f408456..b98636783c 100644 --- a/pkg/util/huawei/natgateway.go +++ b/pkg/util/huawei/natgateway.go @@ -16,12 +16,11 @@ package huawei import ( "time" - "yunion.io/x/pkg/errors" - 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 { @@ -36,7 +35,7 @@ type SNatGateway struct { Description string Spec string Status string - CreatedTime time.Time `json:"created_at"` + CreatedTime string `json:"created_at"` } func (nat *SNatGateway) GetId() string { @@ -70,13 +69,18 @@ func (nat *SNatGateway) GetNatSpec() string { 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 { - return nat.CreatedTime + t, _ := time.Parse("2006-01-02 15:04:05.000000", nat.CreatedTime) + return t } func (nat *SNatGateway) GetExpiredAt() time.Time { @@ -149,15 +153,33 @@ func (nat *SNatGateway) GetINatSTables() ([]cloudprovider.ICloudNatSTable, error } func (region *SRegion) GetNatGateway(natGatewayID string) ([]SNatGateway, error) { - queuies := make(map[string]string) + queues := make(map[string]string) if natGatewayID != "" { - queuies["id"] = natGatewayID + queues["id"] = natGatewayID } natGateways := make([]SNatGateway, 0, 2) - err := doListAllWithMarker(region.ecsClient.NatGateways.List, queuies, &natGateways) + 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 } diff --git a/pkg/util/huawei/natgateway_test.go b/pkg/util/huawei/natgateway_test.go deleted file mode 100644 index 3771971da4..0000000000 --- a/pkg/util/huawei/natgateway_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// 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 ( - "testing" - "yunion.io/x/log" -) - -const ( - PROJECT_ID = "41f6bfe48d7f4455b7754f7c1b11ae34" - ACCESS_KEY = "BLFG27EGJARKKG9HRKGT" - SECRET = "9LzCQcE9JogwQM7t42JaFcFfmPQCuUBdjmXSDibw" -) - -var region *SRegion - -func TestMain(m *testing.M) { - huaweiClient, err := NewHuaweiClient("001", "huaweiZyTest", "", ACCESS_KEY, SECRET, PROJECT_ID, true) - if err != nil { - log.Fatalln(err) - } - regionTmp := huaweiClient.iregions[0] - region = regionTmp.(*SRegion) - m.Run() -} - -func TestSRegion_GetDNatTable(t *testing.T) { - -} - -func TestSregion_GetSNatTable(t *testing.T) { - -} diff --git a/pkg/util/huawei/natstable.go b/pkg/util/huawei/natstable.go index fb8b346ba1..9b0893cce0 100644 --- a/pkg/util/huawei/natstable.go +++ b/pkg/util/huawei/natstable.go @@ -29,6 +29,7 @@ type SNatSTableEntry struct { 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 { @@ -62,22 +63,17 @@ func (nat *SNatSTableEntry) GetNetworkId() string { // getSNatEntries return all snat rules of gateway func (gateway *SNatGateway) getSNatEntries() ([]SNatSTableEntry, error) { - queuies := map[string]string{ - "nat_gateway_id": gateway.GetId(), - } - sNatSTableEntris := make([]SNatSTableEntry, 0, 2) - err := doListAllWithMarker(gateway.region.ecsClient.SNatRules.List, queuies, &sNatSTableEntris) + ret, err := gateway.region.GetSNatTable(gateway.GetId()) if err != nil { - return nil, errors.Wrapf(err, `get snat rule of gateway %q`, gateway.GetId()) + return nil, err } - - for i := range sNatSTableEntris { - sNatSTableEntris[i].gateway = gateway + for i := range ret { + ret[i].gateway = gateway } - return sNatSTableEntris, nil + return ret, nil } -func (region *SRegion) getSNatTable(natGatewayID string) ([]SNatSTableEntry, error) { +func (region *SRegion) GetSNatTable(natGatewayID string) ([]SNatSTableEntry, error) { queuies := map[string]string{ "nat_gateway_id": natGatewayID, } @@ -86,6 +82,17 @@ func (region *SRegion) getSNatTable(natGatewayID string) ([]SNatSTableEntry, err 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 index b1f847e427..4803d91f60 100644 --- a/pkg/util/huawei/shell/natdtable.go +++ b/pkg/util/huawei/shell/natdtable.go @@ -1 +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 index b1f847e427..2a0fbd06c7 100644 --- a/pkg/util/huawei/shell/natgateway.go +++ b/pkg/util/huawei/shell/natgateway.go @@ -1 +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 index b1f847e427..dcb1f57ce7 100644 --- a/pkg/util/huawei/shell/natstable.go +++ b/pkg/util/huawei/shell/natstable.go @@ -1 +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)