yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/hcs/wire.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  	"fmt"
    19  
    20  	"yunion.io/x/pkg/errors"
    21  	"yunion.io/x/pkg/util/netutils"
    22  
    23  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    24  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    25  	"yunion.io/x/cloudmux/pkg/multicloud"
    26  )
    27  
    28  // 华为云的子网有点特殊。子网在整个region可用。
    29  type SWire struct {
    30  	multicloud.SResourceBase
    31  	HcsTags
    32  	region *SRegion
    33  	vpc    *SVpc
    34  }
    35  
    36  func (self *SWire) GetId() string {
    37  	return fmt.Sprintf("%s-%s", self.vpc.GetId(), self.region.GetId())
    38  }
    39  
    40  func (self *SWire) GetName() string {
    41  	return self.GetId()
    42  }
    43  
    44  func (self *SWire) GetGlobalId() string {
    45  	return fmt.Sprintf("%s-%s", self.vpc.GetGlobalId(), self.region.GetGlobalId())
    46  }
    47  
    48  func (self *SWire) GetStatus() string {
    49  	return api.WIRE_STATUS_AVAILABLE
    50  }
    51  
    52  func (self *SWire) GetIVpc() cloudprovider.ICloudVpc {
    53  	return self.vpc
    54  }
    55  
    56  func (self *SWire) GetIZone() cloudprovider.ICloudZone {
    57  	return nil
    58  }
    59  
    60  func (self *SWire) GetINetworks() ([]cloudprovider.ICloudNetwork, error) {
    61  	nets, err := self.region.GetNetwroks(self.vpc.Id)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	ret := []cloudprovider.ICloudNetwork{}
    66  	for i := range nets {
    67  		nets[i].wire = self
    68  		ret = append(ret, &nets[i])
    69  	}
    70  	return ret, nil
    71  }
    72  
    73  func (self *SWire) GetBandwidth() int {
    74  	return 10000
    75  }
    76  
    77  func (self *SWire) GetINetworkById(id string) (cloudprovider.ICloudNetwork, error) {
    78  	net, err := self.region.GetNetwork(id)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	net.wire = self
    83  	return net, nil
    84  }
    85  
    86  /*
    87  华为云子网可用区,类似一个zone标签。即使指定了zone子网在整个region依然是可用。
    88  通过华为web控制台创建子网需要指定可用区。这里是不指定的。
    89  */
    90  func (self *SWire) CreateINetwork(opts *cloudprovider.SNetworkCreateOptions) (cloudprovider.ICloudNetwork, error) {
    91  	net, err := self.region.CreateNetwork(self.vpc.GetId(), opts.Name, opts.Cidr, opts.Desc)
    92  	if err != nil {
    93  		return nil, errors.Wrapf(err, "CreateNetwork")
    94  	}
    95  	net.wire = self
    96  	return net, nil
    97  }
    98  
    99  func getDefaultGateWay(cidr string) (string, error) {
   100  	pref, err := netutils.NewIPV4Prefix(cidr)
   101  	if err != nil {
   102  		return "", errors.Wrap(err, "getDefaultGateWay.NewIPV4Prefix")
   103  	}
   104  	startIp := pref.Address.NetAddr(pref.MaskLen) // 0
   105  	startIp = startIp.StepUp()                    // 1
   106  	return startIp.String(), nil
   107  }
   108  
   109  // https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090590.html
   110  // cidr 掩码长度不能大于28
   111  func (self *SRegion) CreateNetwork(vpcId string, name string, cidr string, desc string) (*SNetwork, error) {
   112  	gateway, err := getDefaultGateWay(cidr)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  
   117  	params := map[string]interface{}{
   118  		"subnet": map[string]interface{}{
   119  			"name":       name,
   120  			"vpc_id":     vpcId,
   121  			"cidr":       cidr,
   122  			"gateway_ip": gateway,
   123  		},
   124  	}
   125  	ret := &SNetwork{}
   126  	return ret, self.vpcCreate("subnets", params, ret)
   127  }