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)