From 666def70cc9b13845ba47cdca2105bbe1a7bcfb2 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Jul 2019 20:21:30 +0800 Subject: [PATCH] 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