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 }