| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- // 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 hcso
- import (
- "strings"
- "time"
- "yunion.io/x/jsonutils"
- "yunion.io/x/pkg/errors"
- billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
- api "yunion.io/x/cloudmux/pkg/apis/compute"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/cloudmux/pkg/multicloud"
- "yunion.io/x/cloudmux/pkg/multicloud/huawei"
- )
- type SNatGateway struct {
- multicloud.SNatGatewayBase
- huawei.HuaweiTags
- region *SRegion
- ID string
- Name string
- Description string
- Spec string
- Status string
- InternalNetworkId string
- CreatedTime string `json:"created_at"`
- }
- func (gateway *SNatGateway) GetId() string {
- return gateway.ID
- }
- func (gateway *SNatGateway) GetName() string {
- return gateway.Name
- }
- func (gateway *SNatGateway) GetGlobalId() string {
- return gateway.GetId()
- }
- func (gateway *SNatGateway) GetStatus() string {
- return NatResouceStatusTransfer(gateway.Status)
- }
- func (self *SNatGateway) Delete() error {
- return self.region.DeleteNatGateway(self.ID)
- }
- func (self *SNatGateway) Refresh() error {
- nat, err := self.region.GetNatGateway(self.ID)
- if err != nil {
- return errors.Wrapf(err, "GetNatGateway(%s)", self.ID)
- }
- return jsonutils.Update(self, nat)
- }
- func (self *SNatGateway) GetINetworkId() string {
- return self.InternalNetworkId
- }
- func (self *SNatGateway) GetNetworkType() string {
- return api.NAT_NETWORK_TYPE_INTERNET
- }
- func (gateway *SNatGateway) GetNatSpec() string {
- switch gateway.Spec {
- case "1":
- return api.NAT_SPEC_SMALL
- case "2":
- return api.NAT_SPEC_MIDDLE
- case "3":
- return api.NAT_SPEC_LARGE
- case "4":
- return api.NAT_SPEC_XLARGE
- }
- return gateway.Spec
- }
- func (gateway *SNatGateway) GetDescription() string {
- return gateway.Description
- }
- func (gateway *SNatGateway) GetBillingType() string {
- // Up to 2019.07.17, only support post pay
- return billing_api.BILLING_TYPE_POSTPAID
- }
- func (gateway *SNatGateway) GetCreatedAt() time.Time {
- t, _ := time.Parse("2006-01-02 15:04:05.000000", gateway.CreatedTime)
- return t
- }
- func (gateway *SNatGateway) GetExpiredAt() time.Time {
- // no support for expired time
- return time.Time{}
- }
- func (gateway *SNatGateway) GetIEips() ([]cloudprovider.ICloudEIP, error) {
- IEips, err := gateway.region.GetIEips()
- if err != nil {
- return nil, errors.Wrapf(err, `get all Eips of region %q error`, gateway.region.GetId())
- }
- dNatTables, err := gateway.GetINatDTable()
- if err != nil {
- return nil, errors.Wrapf(err, `get all DNatTable of gateway %q error`, gateway.GetId())
- }
- sNatTables, err := gateway.GetINatSTable()
- if err != nil {
- return nil, errors.Wrapf(err, `get all SNatTable of gateway %q error`, gateway.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 (gateway *SNatGateway) GetINatDTable() ([]cloudprovider.ICloudNatDEntry, error) {
- dNatTable, err := gateway.getNatDTable()
- if err != nil {
- return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId())
- }
- ret := make([]cloudprovider.ICloudNatDEntry, len(dNatTable))
- for i := range dNatTable {
- ret[i] = &dNatTable[i]
- }
- return ret, nil
- }
- func (gateway *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) {
- sNatTable, err := gateway.getNatSTable()
- if err != nil {
- return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId())
- }
- ret := make([]cloudprovider.ICloudNatSEntry, len(sNatTable))
- for i := range sNatTable {
- ret[i] = &sNatTable[i]
- }
- return ret, nil
- }
- func (gateway *SNatGateway) CreateINatDEntry(rule cloudprovider.SNatDRule) (cloudprovider.ICloudNatDEntry, error) {
- dnat, err := gateway.region.CreateNatDEntry(rule, gateway.GetId())
- if err != nil {
- return nil, err
- }
- dnat.gateway = gateway
- return &dnat, nil
- }
- func (gateway *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprovider.ICloudNatSEntry, error) {
- snat, err := gateway.region.CreateNatSEntry(rule, gateway.GetId())
- if err != nil {
- return nil, err
- }
- snat.gateway = gateway
- return &snat, nil
- }
- func (gateway *SNatGateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) {
- dnat, err := gateway.region.GetNatDEntryByID(id)
- if err != nil {
- return nil, err
- }
- dnat.gateway = gateway
- return &dnat, nil
- }
- func (gateway *SNatGateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) {
- snat, err := gateway.region.GetNatSEntryByID(id)
- if err != nil {
- return nil, err
- }
- snat.gateway = gateway
- return &snat, nil
- }
- func (region *SRegion) GetNatGateways(vpcID, natGatewayID string) ([]SNatGateway, error) {
- queues := make(map[string]string)
- if len(natGatewayID) != 0 {
- queues["id"] = natGatewayID
- }
- if len(vpcID) != 0 {
- queues["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 natgatewayid")
- }
- for i := range natGateways {
- natGateways[i].region = region
- }
- return natGateways, nil
- }
- func (region *SRegion) CreateNatDEntry(rule cloudprovider.SNatDRule, gatewayID string) (SNatDEntry, error) {
- params := make(map[string]interface{})
- params["nat_gateway_id"] = gatewayID
- params["private_ip"] = rule.InternalIP
- params["internal_service_port"] = rule.InternalPort
- params["floating_ip_id"] = rule.ExternalIPID
- params["external_service_port"] = rule.ExternalPort
- params["protocol"] = rule.Protocol
- packParams := map[string]map[string]interface{}{
- "dnat_rule": params,
- }
- ret := SNatDEntry{}
- err := DoCreate(region.ecsClient.DNatRules.Create, jsonutils.Marshal(packParams), &ret)
- if err != nil {
- return SNatDEntry{}, errors.Wrapf(err, `create dnat rule of nat gateway %q failed`, gatewayID)
- }
- return ret, nil
- }
- func (region *SRegion) CreateNatSEntry(rule cloudprovider.SNatSRule, gatewayID string) (SNatSEntry, error) {
- params := make(map[string]interface{})
- params["nat_gateway_id"] = gatewayID
- if len(rule.NetworkID) != 0 {
- params["network_id"] = rule.NetworkID
- }
- if len(rule.SourceCIDR) != 0 {
- params["cidr"] = rule.SourceCIDR
- }
- params["floating_ip_id"] = rule.ExternalIPID
- packParams := map[string]map[string]interface{}{
- "snat_rule": params,
- }
- ret := SNatSEntry{}
- err := DoCreate(region.ecsClient.SNatRules.Create, jsonutils.Marshal(packParams), &ret)
- if err != nil {
- return SNatSEntry{}, errors.Wrapf(err, `create snat rule of nat gateway %q failed`, gatewayID)
- }
- return ret, nil
- }
- func (region *SRegion) GetNatDEntryByID(id string) (SNatDEntry, error) {
- dnat := SNatDEntry{}
- err := DoGet(region.ecsClient.DNatRules.Get, id, map[string]string{}, &dnat)
- if err != nil {
- return SNatDEntry{}, err
- }
- return dnat, nil
- }
- func (region *SRegion) GetNatSEntryByID(id string) (SNatSEntry, error) {
- snat := SNatSEntry{}
- err := DoGet(region.ecsClient.SNatRules.Get, id, map[string]string{}, &snat)
- if err != nil {
- return SNatSEntry{}, cloudprovider.ErrNotFound
- }
- return snat, 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
- }
- }
- func (self *SRegion) GetNatGateway(id string) (*SNatGateway, error) {
- resp, err := self.ecsClient.NatGateways.Get(id, nil)
- if err != nil {
- return nil, errors.Wrapf(err, "NatGateways.Get(%s)", id)
- }
- nat := &SNatGateway{region: self}
- err = resp.Unmarshal(nat)
- return nat, errors.Wrap(err, "resp.Unmarshal")
- }
- func (self *SVpc) CreateINatGateway(opts *cloudprovider.NatGatewayCreateOptions) (cloudprovider.ICloudNatGateway, error) {
- nat, err := self.region.CreateNatGateway(opts)
- if err != nil {
- return nil, errors.Wrapf(err, "CreateNatGateway")
- }
- return nat, nil
- }
- func (self *SRegion) CreateNatGateway(opts *cloudprovider.NatGatewayCreateOptions) (*SNatGateway, error) {
- spec := ""
- switch strings.ToLower(opts.NatSpec) {
- case api.NAT_SPEC_SMALL:
- spec = "1"
- case api.NAT_SPEC_MIDDLE:
- spec = "2"
- case api.NAT_SPEC_LARGE:
- spec = "3"
- case api.NAT_SPEC_XLARGE:
- spec = "4"
- }
- params := jsonutils.Marshal(map[string]map[string]interface{}{
- "nat_gateway": map[string]interface{}{
- "name": opts.Name,
- "description": opts.Desc,
- "router_id": opts.VpcId,
- "internal_network_id": opts.NetworkId,
- "spec": spec,
- },
- })
- resp, err := self.ecsClient.NatGateways.Create(params)
- if err != nil {
- return nil, errors.Wrap(err, "AsyncCreate")
- }
- nat := &SNatGateway{region: self}
- err = resp.Unmarshal(nat)
- if err != nil {
- return nil, errors.Wrapf(err, "resp.Unmarshal")
- }
- return nat, nil
- }
- func (self *SRegion) DeleteNatGateway(id string) error {
- _, err := self.ecsClient.NatGateways.Delete(id, nil)
- return errors.Wrapf(err, "NatGateways.Delete(%s)", id)
- }
|