| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- // 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 (
- "net/url"
- "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"
- )
- type SNatGateway struct {
- multicloud.SNatGatewayBase
- 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_INTRANET
- }
- 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) {
- ports, err := gateway.region.GetPorts(gateway.ID)
- if err != nil {
- return nil, errors.Wrapf(err, "GetPorts(%s)", gateway.ID)
- }
- ret := []cloudprovider.ICloudEIP{}
- for i := range ports {
- eips, err := gateway.region.GetEips(ports[i].ID, nil)
- if err != nil {
- return nil, err
- }
- for i := range eips {
- eips[i].region = gateway.region
- ret = append(ret, &eips[i])
- }
- }
- return ret, nil
- }
- func (gateway *SNatGateway) GetINatDTable() ([]cloudprovider.ICloudNatDEntry, error) {
- dNatTable, err := gateway.region.GetNatDEntries(gateway.ID)
- 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 {
- dNatTable[i].gateway = gateway
- ret[i] = &dNatTable[i]
- }
- return ret, nil
- }
- func (gateway *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) {
- sNatTable, err := gateway.region.GetNatSEntries(gateway.ID)
- 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 {
- sNatTable[i].gateway = gateway
- 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, id string) ([]SNatGateway, error) {
- query := url.Values{}
- if len(id) != 0 {
- query.Set("id", id)
- }
- if len(vpcId) != 0 {
- query.Set("vpc_id", vpcId)
- }
- ret := []SNatGateway{}
- for {
- resp, err := region.list(SERVICE_NAT, "private-nat/gateways", query)
- if err != nil {
- return nil, err
- }
- part := struct {
- Gateways []SNatGateway
- PageInfo sPageInfo
- }{}
- err = resp.Unmarshal(&part)
- if err != nil {
- return nil, err
- }
- ret = append(ret, part.Gateways...)
- if len(part.PageInfo.NextMarker) == 0 || len(part.Gateways) == 0 {
- break
- }
- query.Set("marker", part.PageInfo.NextMarker)
- }
- return ret, nil
- }
- func (region *SRegion) CreateNatDEntry(rule cloudprovider.SNatDRule, gatewayID string) (*SNatDEntry, error) {
- params := make(map[string]interface{})
- params["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
- resp, err := region.post(SERVICE_NAT, "private-nat/dnat-rules", map[string]interface{}{"dnat_rule": params})
- if err != nil {
- return nil, errors.Wrapf(err, "create dnat")
- }
- ret := &SNatDEntry{}
- err = resp.Unmarshal(ret, "dnat_rule")
- if err != nil {
- return nil, err
- }
- return ret, nil
- }
- func (region *SRegion) CreateNatSEntry(rule cloudprovider.SNatSRule, gatewayId string) (*SNatSEntry, error) {
- params := make(map[string]interface{})
- params["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
- resp, err := region.post(SERVICE_NAT, "private-nat/snat-rules", map[string]interface{}{"snat_rule": params})
- if err != nil {
- return nil, errors.Wrapf(err, "create snat")
- }
- ret := &SNatSEntry{}
- err = resp.Unmarshal(ret, "snat_rule")
- if err != nil {
- return nil, err
- }
- return ret, nil
- }
- func (region *SRegion) GetNatDEntryByID(id string) (*SNatDEntry, error) {
- resp, err := region.list(SERVICE_NAT, "private-nat/dnat-rules/"+id, nil)
- if err != nil {
- return nil, err
- }
- ret := &SNatDEntry{}
- err = resp.Unmarshal(ret, "dnat_rule")
- if err != nil {
- return nil, err
- }
- return ret, nil
- }
- func (region *SRegion) GetNatSEntryByID(id string) (*SNatSEntry, error) {
- resp, err := region.list(SERVICE_NAT, "private-nat/snat-rules/"+id, nil)
- if err != nil {
- return nil, err
- }
- ret := &SNatSEntry{}
- err = resp.Unmarshal(ret, "snat_rule")
- if err != nil {
- return nil, err
- }
- return ret, 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.list(SERVICE_NAT, "private-nat/gateways/"+id, nil)
- if err != nil {
- return nil, err
- }
- nat := &SNatGateway{region: self}
- err = resp.Unmarshal(nat, "gateway")
- if err != nil {
- return nil, err
- }
- return nat, nil
- }
- 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 := 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.post(SERVICE_NAT, "private-nat/gateways", params)
- if err != nil {
- return nil, errors.Wrap(err, "create nat")
- }
- nat := &SNatGateway{region: self}
- err = resp.Unmarshal(nat, "gateway")
- if err != nil {
- return nil, errors.Wrapf(err, "resp.Unmarshal")
- }
- return nat, nil
- }
- func (self *SRegion) DeleteNatGateway(id string) error {
- _, err := self.delete(SERVICE_NAT, "private-nat/gateways/"+id)
- return err
- }
|