yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/hcs/natgateway.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package hcs
    16  
    17  import (
    18  	"net/url"
    19  	"strings"
    20  	"time"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/pkg/errors"
    24  
    25  	billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
    26  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    27  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    28  	"yunion.io/x/cloudmux/pkg/multicloud"
    29  )
    30  
    31  type SNatGateway struct {
    32  	multicloud.SNatGatewayBase
    33  	HcsTags
    34  	region *SRegion
    35  
    36  	Id                string
    37  	Name              string
    38  	Description       string
    39  	Spec              string
    40  	Status            string
    41  	InternalNetworkId string
    42  	CreatedTime       string `json:"created_at"`
    43  }
    44  
    45  func (gateway *SNatGateway) GetId() string {
    46  	return gateway.Id
    47  }
    48  
    49  func (gateway *SNatGateway) GetName() string {
    50  	return gateway.Name
    51  }
    52  
    53  func (gateway *SNatGateway) GetGlobalId() string {
    54  	return gateway.GetId()
    55  }
    56  
    57  func (gateway *SNatGateway) GetStatus() string {
    58  	return NatResouceStatusTransfer(gateway.Status)
    59  }
    60  
    61  func (self *SNatGateway) Delete() error {
    62  	return self.region.DeleteNatGateway(self.Id)
    63  }
    64  
    65  func (self *SNatGateway) Refresh() error {
    66  	nat, err := self.region.GetNatGateway(self.Id)
    67  	if err != nil {
    68  		return errors.Wrapf(err, "GetNatGateway(%s)", self.Id)
    69  	}
    70  	return jsonutils.Update(self, nat)
    71  }
    72  
    73  func (self *SNatGateway) GetINetworkId() string {
    74  	return self.InternalNetworkId
    75  }
    76  
    77  func (gateway *SNatGateway) GetNatSpec() string {
    78  	switch gateway.Spec {
    79  	case "1":
    80  		return api.NAT_SPEC_SMALL
    81  	case "2":
    82  		return api.NAT_SPEC_MIDDLE
    83  	case "3":
    84  		return api.NAT_SPEC_LARGE
    85  	case "4":
    86  		return api.NAT_SPEC_XLARGE
    87  	}
    88  	return gateway.Spec
    89  }
    90  
    91  func (gateway *SNatGateway) GetDescription() string {
    92  	return gateway.Description
    93  }
    94  
    95  func (gateway *SNatGateway) GetBillingType() string {
    96  	return billing_api.BILLING_TYPE_POSTPAID
    97  }
    98  
    99  func (gateway *SNatGateway) GetCreatedAt() time.Time {
   100  	t, _ := time.Parse("2006-01-02 15:04:05.000000", gateway.CreatedTime)
   101  	return t
   102  }
   103  
   104  func (gateway *SNatGateway) GetExpiredAt() time.Time {
   105  	return time.Time{}
   106  }
   107  
   108  func (gateway *SNatGateway) GetIEips() ([]cloudprovider.ICloudEIP, error) {
   109  	IEips, err := gateway.region.GetIEips()
   110  	if err != nil {
   111  		return nil, errors.Wrapf(err, `get all Eips of region %q error`, gateway.region.GetId())
   112  	}
   113  	dNatTables, err := gateway.GetINatDTable()
   114  	if err != nil {
   115  		return nil, errors.Wrapf(err, `get all DNatTable of gateway %q error`, gateway.GetId())
   116  	}
   117  	sNatTables, err := gateway.GetINatSTable()
   118  	if err != nil {
   119  		return nil, errors.Wrapf(err, `get all SNatTable of gateway %q error`, gateway.GetId())
   120  	}
   121  
   122  	// Get natIPSet of nat rules
   123  	natIPSet := make(map[string]struct{})
   124  	for _, snat := range sNatTables {
   125  		natIPSet[snat.GetIP()] = struct{}{}
   126  	}
   127  	for _, dnat := range dNatTables {
   128  		natIPSet[dnat.GetExternalIp()] = struct{}{}
   129  	}
   130  
   131  	// Add Eip whose GetIpAddr() in natIPSet to ret
   132  	ret := make([]cloudprovider.ICloudEIP, 0, 2)
   133  	for i := range IEips {
   134  		if _, ok := natIPSet[IEips[i].GetIpAddr()]; ok {
   135  			ret = append(ret, IEips[i])
   136  		}
   137  	}
   138  	return ret, nil
   139  }
   140  
   141  func (gateway *SNatGateway) GetINatDTable() ([]cloudprovider.ICloudNatDEntry, error) {
   142  	dNatTable, err := gateway.getNatDTable()
   143  	if err != nil {
   144  		return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId())
   145  	}
   146  	ret := make([]cloudprovider.ICloudNatDEntry, len(dNatTable))
   147  	for i := range dNatTable {
   148  		ret[i] = &dNatTable[i]
   149  	}
   150  	return ret, nil
   151  }
   152  
   153  func (gateway *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) {
   154  	sNatTable, err := gateway.getNatSTable()
   155  	if err != nil {
   156  		return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId())
   157  	}
   158  	ret := make([]cloudprovider.ICloudNatSEntry, len(sNatTable))
   159  	for i := range sNatTable {
   160  		ret[i] = &sNatTable[i]
   161  	}
   162  	return ret, nil
   163  }
   164  
   165  func (gateway *SNatGateway) CreateINatDEntry(rule cloudprovider.SNatDRule) (cloudprovider.ICloudNatDEntry, error) {
   166  	dnat, err := gateway.region.CreateNatDEntry(rule, gateway.GetId())
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  	dnat.gateway = gateway
   171  	return dnat, nil
   172  }
   173  
   174  func (gateway *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprovider.ICloudNatSEntry, error) {
   175  	snat, err := gateway.region.CreateNatSEntry(rule, gateway.GetId())
   176  	if err != nil {
   177  		return nil, err
   178  	}
   179  	snat.gateway = gateway
   180  	return snat, nil
   181  }
   182  
   183  func (gateway *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) {
   184  	dnat, err := gateway.region.GetNatDEntry(id)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  	dnat.gateway = gateway
   189  	return dnat, nil
   190  }
   191  
   192  func (gateway *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) {
   193  	snat, err := gateway.region.GetNatSEntry(id)
   194  	if err != nil {
   195  		return nil, err
   196  	}
   197  	snat.gateway = gateway
   198  	return snat, nil
   199  }
   200  
   201  func (self *SRegion) GetNatGateways(vpcId string) ([]SNatGateway, error) {
   202  	query := url.Values{}
   203  	if len(vpcId) > 0 {
   204  		query.Set("router_id", vpcId)
   205  	}
   206  	ret := []SNatGateway{}
   207  	return ret, self.list("nat", "v2.0", "nat_gateways", query, &ret)
   208  }
   209  
   210  func NatResouceStatusTransfer(status string) string {
   211  	// In Huawei Cloud, there are isx resource status of Nat, "ACTIVE", "PENDING_CREATE",
   212  	// "PENDING_UPDATE", "PENDING_DELETE", "EIP_FREEZED", "INACTIVE".
   213  	switch status {
   214  	case "ACTIVE":
   215  		return api.NAT_STAUTS_AVAILABLE
   216  	case "PENDING_CREATE":
   217  		return api.NAT_STATUS_ALLOCATE
   218  	case "PENDING_UPDATE", "PENDING_DELETE":
   219  		return api.NAT_STATUS_DEPLOYING
   220  	default:
   221  		return api.NAT_STATUS_UNKNOWN
   222  	}
   223  }
   224  
   225  func (self *SRegion) GetNatGateway(id string) (*SNatGateway, error) {
   226  	ret := &SNatGateway{region: self}
   227  	return ret, self.get("nat", "v2.0", "nat_gateways/"+id, ret)
   228  }
   229  
   230  func (self *SVpc) CreateINatGateway(opts *cloudprovider.NatGatewayCreateOptions) (cloudprovider.ICloudNatGateway, error) {
   231  	nat, err := self.region.CreateNatGateway(opts)
   232  	if err != nil {
   233  		return nil, errors.Wrapf(err, "CreateNatGateway")
   234  	}
   235  	return nat, nil
   236  }
   237  
   238  func (self *SRegion) CreateNatGateway(opts *cloudprovider.NatGatewayCreateOptions) (*SNatGateway, error) {
   239  	spec := ""
   240  	switch strings.ToLower(opts.NatSpec) {
   241  	case api.NAT_SPEC_SMALL:
   242  		spec = "1"
   243  	case api.NAT_SPEC_MIDDLE:
   244  		spec = "2"
   245  	case api.NAT_SPEC_LARGE:
   246  		spec = "3"
   247  	case api.NAT_SPEC_XLARGE:
   248  		spec = "4"
   249  	}
   250  	params := map[string]interface{}{
   251  		"nat_gateway": map[string]interface{}{
   252  			"name":                opts.Name,
   253  			"description":         opts.Desc,
   254  			"router_id":           opts.VpcId,
   255  			"internal_network_id": opts.NetworkId,
   256  			"spec":                spec,
   257  		},
   258  	}
   259  	ret := SNatGateway{region: self}
   260  	return &ret, self.create("nat", "v2.0", "nat_gateways", params, &ret)
   261  }
   262  
   263  func (self *SRegion) DeleteNatGateway(id string) error {
   264  	return self.delete("nat", "v2.0", "nat_gateways/"+id)
   265  }