yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/ucloud/vpc.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 ucloud
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"yunion.io/x/jsonutils"
    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  type SVPC struct {
    29  	multicloud.SVpc
    30  	UcloudTags
    31  
    32  	region *SRegion
    33  
    34  	iwires    []cloudprovider.ICloudWire
    35  	secgroups []cloudprovider.ICloudSecurityGroup
    36  
    37  	CreateTime  int64         `json:"CreateTime"`
    38  	Name        string        `json:"Name"`
    39  	Network     []string      `json:"Network"`
    40  	NetworkInfo []NetworkInfo `json:"NetworkInfo"`
    41  	SubnetCount int           `json:"SubnetCount"`
    42  	Tag         string        `json:"Tag"`
    43  	UpdateTime  int64         `json:"UpdateTime"`
    44  	VPCID       string        `json:"VPCId"`
    45  }
    46  
    47  type NetworkInfo struct {
    48  	Network     string `json:"Network"`
    49  	SubnetCount int    `json:"SubnetCount"`
    50  }
    51  
    52  func (self *SVPC) addWire(wire *SWire) {
    53  	if self.iwires == nil {
    54  		self.iwires = make([]cloudprovider.ICloudWire, 0)
    55  	}
    56  	self.iwires = append(self.iwires, wire)
    57  }
    58  
    59  func (self *SVPC) GetId() string {
    60  	return self.VPCID
    61  }
    62  
    63  func (self *SVPC) GetName() string {
    64  	if len(self.Name) > 0 {
    65  		return self.Name
    66  	}
    67  	return self.VPCID
    68  }
    69  
    70  func (self *SVPC) GetGlobalId() string {
    71  	return self.GetId()
    72  }
    73  
    74  func (self *SVPC) GetStatus() string {
    75  	return api.VPC_STATUS_AVAILABLE
    76  }
    77  
    78  func (self *SVPC) Refresh() error {
    79  	new, err := self.region.getVpc(self.GetId())
    80  	if err != nil {
    81  		return err
    82  	}
    83  	return jsonutils.Update(self, new)
    84  }
    85  
    86  func (self *SVPC) IsEmulated() bool {
    87  	return false
    88  }
    89  
    90  func (self *SVPC) GetRegion() cloudprovider.ICloudRegion {
    91  	return self.region
    92  }
    93  
    94  func (self *SVPC) GetIsDefault() bool {
    95  	return false
    96  }
    97  
    98  func (self *SVPC) GetCidrBlock() string {
    99  	return strings.Join(self.Network, ",")
   100  }
   101  
   102  func (self *SVPC) GetIWires() ([]cloudprovider.ICloudWire, error) {
   103  	if self.iwires == nil {
   104  		err := self.fetchNetworks()
   105  		if err != nil {
   106  			return nil, err
   107  		}
   108  	}
   109  	return self.iwires, nil
   110  }
   111  
   112  // 由于Ucloud 安全组和vpc没有直接关联,这里是返回同一个项目下的防火墙列表,会导致重复同步的问题。
   113  // https://docs.ucloud.cn/api/unet-api/grant_firewall
   114  func (self *SVPC) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
   115  	if self.secgroups == nil {
   116  		err := self.fetchSecurityGroups()
   117  		if err != nil {
   118  			return nil, err
   119  		}
   120  	}
   121  	return self.secgroups, nil
   122  }
   123  
   124  func (self *SVPC) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
   125  	rts := []cloudprovider.ICloudRouteTable{}
   126  	return rts, nil
   127  }
   128  
   129  func (self *SVPC) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudRouteTable, error) {
   130  	return nil, cloudprovider.ErrNotSupported
   131  }
   132  
   133  func (self *SVPC) Delete() error {
   134  	return self.region.DeleteVpc(self.GetId())
   135  }
   136  
   137  func (self *SVPC) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) {
   138  	if self.iwires == nil {
   139  		err := self.fetchNetworks()
   140  		if err != nil {
   141  			return nil, err
   142  		}
   143  	}
   144  	for i := 0; i < len(self.iwires); i += 1 {
   145  		if self.iwires[i].GetGlobalId() == wireId {
   146  			return self.iwires[i], nil
   147  		}
   148  	}
   149  	return nil, cloudprovider.ErrNotFound
   150  }
   151  
   152  func (self *SVPC) fetchNetworks() error {
   153  	networks, err := self.region.GetNetworks(self.GetId())
   154  	if err != nil {
   155  		return err
   156  	}
   157  
   158  	for i := 0; i < len(networks); i += 1 {
   159  		wire := self.getWireByRegionId(self.region.GetId())
   160  		networks[i].wire = wire
   161  		wire.addNetwork(&networks[i])
   162  	}
   163  
   164  	return nil
   165  }
   166  
   167  func (self *SVPC) getWireByRegionId(regionId string) *SWire {
   168  	if len(regionId) == 0 {
   169  		return nil
   170  	}
   171  
   172  	for i := 0; i < len(self.iwires); i++ {
   173  		wire := self.iwires[i].(*SWire)
   174  
   175  		if wire.region.GetId() == regionId {
   176  			return wire
   177  		}
   178  	}
   179  
   180  	return nil
   181  }
   182  
   183  func (self *SRegion) getVpc(vpcId string) (*SVPC, error) {
   184  	vpcs, err := self.GetVpcs(vpcId)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  
   189  	if len(vpcs) == 1 {
   190  		return &vpcs[0], nil
   191  	} else if len(vpcs) == 0 {
   192  		return nil, cloudprovider.ErrNotFound
   193  	} else {
   194  		return nil, fmt.Errorf("getVpc %s %d found", vpcId, len(vpcs))
   195  	}
   196  }
   197  
   198  // https://docs.ucloud.cn/api/vpc2.0-api/delete_vpc
   199  func (self *SRegion) DeleteVpc(vpcId string) error {
   200  	params := NewUcloudParams()
   201  	params.Set("VPCId", vpcId)
   202  	return self.DoAction("DeleteVPC", params, nil)
   203  }
   204  
   205  // https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090625.html
   206  func (self *SRegion) GetVpcs(vpcId string) ([]SVPC, error) {
   207  	vpcs := make([]SVPC, 0)
   208  	params := NewUcloudParams()
   209  	if len(vpcId) > 0 {
   210  		params.Set("VPCIds.0", vpcId)
   211  	}
   212  
   213  	err := self.DoListAll("DescribeVPC", params, &vpcs)
   214  	return vpcs, err
   215  }
   216  
   217  func (self *SRegion) GetNetworks(vpcId string) ([]SNetwork, error) {
   218  	params := NewUcloudParams()
   219  	if len(vpcId) > 0 {
   220  		params.Set("VPCId", vpcId)
   221  	}
   222  
   223  	networks := make([]SNetwork, 0)
   224  	err := self.DoAction("DescribeSubnet", params, &networks)
   225  	return networks, err
   226  }
   227  
   228  // UCLOUD 同一个项目共用安全组(防火墙)
   229  func (self *SVPC) fetchSecurityGroups() error {
   230  	secgroups, err := self.region.GetSecurityGroups("", "", "")
   231  	if err != nil {
   232  		return err
   233  	}
   234  
   235  	self.secgroups = make([]cloudprovider.ICloudSecurityGroup, len(secgroups))
   236  	for i := 0; i < len(secgroups); i++ {
   237  		secgroups[i].vpc = self
   238  		secgroups[i].region = self.region
   239  		self.secgroups[i] = &secgroups[i]
   240  	}
   241  	return nil
   242  }