yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/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 huawei 16 17 import ( 18 "strings" 19 20 "yunion.io/x/jsonutils" 21 "yunion.io/x/pkg/errors" 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 // https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090625.html 29 type SVpc struct { 30 multicloud.SVpc 31 HuaweiTags 32 33 region *SRegion 34 35 iwires []cloudprovider.ICloudWire 36 secgroups []cloudprovider.ICloudSecurityGroup 37 38 ID string `json:"id"` 39 Name string `json:"name"` 40 CIDR string `json:"cidr"` 41 Status string `json:"status"` 42 EnterpriseProjectID string `json:"enterprise_project_id"` 43 } 44 45 func (self *SVpc) addWire(wire *SWire) { 46 if self.iwires == nil { 47 self.iwires = make([]cloudprovider.ICloudWire, 0) 48 } 49 self.iwires = append(self.iwires, wire) 50 } 51 52 func (self *SVpc) getWireByRegionId(regionId string) *SWire { 53 if len(regionId) == 0 { 54 return nil 55 } 56 57 for i := 0; i < len(self.iwires); i++ { 58 wire := self.iwires[i].(*SWire) 59 60 if wire.region.GetId() == regionId { 61 return wire 62 } 63 } 64 65 return nil 66 } 67 68 func (self *SVpc) fetchNetworks() error { 69 networks, err := self.region.GetNetwroks(self.ID) 70 if err != nil { 71 return err 72 } 73 74 // ??????? 75 if len(networks) == 0 { 76 self.iwires = append(self.iwires, &SWire{region: self.region, vpc: self}) 77 return nil 78 } 79 80 for i := 0; i < len(networks); i += 1 { 81 wire := self.getWireByRegionId(self.region.GetId()) 82 networks[i].wire = wire 83 wire.addNetwork(&networks[i]) 84 } 85 return nil 86 } 87 88 // 华为云安全组可以被同region的VPC使用 89 func (self *SVpc) fetchSecurityGroups() error { 90 secgroups, err := self.region.GetSecurityGroups("", "") 91 if err != nil { 92 return err 93 } 94 95 self.secgroups = make([]cloudprovider.ICloudSecurityGroup, len(secgroups)) 96 for i := 0; i < len(secgroups); i++ { 97 self.secgroups[i] = &secgroups[i] 98 } 99 return nil 100 } 101 102 func (self *SVpc) GetId() string { 103 return self.ID 104 } 105 106 func (self *SVpc) GetName() string { 107 if len(self.Name) > 0 { 108 return self.Name 109 } 110 return self.ID 111 } 112 113 func (self *SVpc) GetGlobalId() string { 114 return self.ID 115 } 116 117 func (self *SVpc) GetStatus() string { 118 return api.VPC_STATUS_AVAILABLE 119 } 120 121 func (self *SVpc) Refresh() error { 122 new, err := self.region.getVpc(self.GetId()) 123 if err != nil { 124 return err 125 } 126 return jsonutils.Update(self, new) 127 } 128 129 func (self *SVpc) IsEmulated() bool { 130 return false 131 } 132 133 func (self *SVpc) GetRegion() cloudprovider.ICloudRegion { 134 return self.region 135 } 136 137 func (self *SVpc) GetIsDefault() bool { 138 // 华为云没有default vpc. 139 return false 140 } 141 142 func (self *SVpc) GetCidrBlock() string { 143 return self.CIDR 144 } 145 146 func (self *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) { 147 if self.iwires == nil { 148 err := self.fetchNetworks() 149 if err != nil { 150 return nil, err 151 } 152 } 153 return self.iwires, nil 154 } 155 156 func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { 157 if self.secgroups == nil { 158 err := self.fetchSecurityGroups() 159 if err != nil { 160 return nil, err 161 } 162 } 163 return self.secgroups, nil 164 } 165 166 func (self *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) { 167 rtbs, err := self.region.GetRouteTables(self.ID) 168 if err != nil { 169 return nil, err 170 } 171 ret := []cloudprovider.ICloudRouteTable{} 172 for i := range rtbs { 173 rtbs[i].vpc = self 174 ret = append(ret, &rtbs[i]) 175 } 176 return ret, nil 177 } 178 179 func (self *SVpc) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudRouteTable, error) { 180 rtb, err := self.region.GetRouteTable(routeTableId) 181 if err != nil { 182 return nil, err 183 } 184 rtb.vpc = self 185 return rtb, nil 186 } 187 188 func (self *SVpc) Delete() error { 189 // todo: 确定删除VPC的逻辑 190 return self.region.DeleteVpc(self.GetId()) 191 } 192 193 func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) { 194 if self.iwires == nil { 195 err := self.fetchNetworks() 196 if err != nil { 197 return nil, err 198 } 199 } 200 for i := 0; i < len(self.iwires); i += 1 { 201 if self.iwires[i].GetGlobalId() == wireId { 202 return self.iwires[i], nil 203 } 204 } 205 return nil, cloudprovider.ErrNotFound 206 } 207 208 func (self *SVpc) GetINatGateways() ([]cloudprovider.ICloudNatGateway, error) { 209 nats, err := self.region.GetNatGateways(self.GetId(), "") 210 if err != nil { 211 return nil, err 212 } 213 ret := make([]cloudprovider.ICloudNatGateway, len(nats)) 214 for i := 0; i < len(nats); i++ { 215 ret[i] = &nats[i] 216 } 217 return ret, nil 218 } 219 220 func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) { 221 svpcPCs, err := self.getVpcPeeringConnections() 222 if err != nil { 223 return nil, errors.Wrap(err, "self.getVpcPeeringConnections()") 224 } 225 ivpcPCs := []cloudprovider.ICloudVpcPeeringConnection{} 226 for i := range svpcPCs { 227 ivpcPCs = append(ivpcPCs, &svpcPCs[i]) 228 } 229 return ivpcPCs, nil 230 } 231 232 func (self *SVpc) GetICloudAccepterVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) { 233 svpcPCs, err := self.getAccepterVpcPeeringConnections() 234 if err != nil { 235 return nil, errors.Wrap(err, "self.getAccepterVpcPeeringConnections()") 236 } 237 ivpcPCs := []cloudprovider.ICloudVpcPeeringConnection{} 238 for i := range svpcPCs { 239 ivpcPCs = append(ivpcPCs, &svpcPCs[i]) 240 } 241 return ivpcPCs, nil 242 } 243 244 func (self *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) { 245 svpcPC, err := self.getVpcPeeringConnectionById(id) 246 if err != nil { 247 return nil, errors.Wrapf(err, "self.getVpcPeeringConnectionById(%s)", id) 248 } 249 return svpcPC, nil 250 } 251 252 func (self *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) { 253 svpcPC, err := self.region.CreateVpcPeering(self.GetId(), opts) 254 if err != nil { 255 return nil, errors.Wrapf(err, "self.region.CreateVpcPeering(%s,%s)", self.GetId(), jsonutils.Marshal(opts).String()) 256 } 257 svpcPC.vpc = self 258 return svpcPC, nil 259 } 260 func (self *SVpc) AcceptICloudVpcPeeringConnection(id string) error { 261 vpcPC, err := self.getVpcPeeringConnectionById(id) 262 if err != nil { 263 return errors.Wrapf(err, "self.getVpcPeeringConnectionById(%s)", id) 264 } 265 if vpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_ACTIVE { 266 return nil 267 } 268 if vpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN { 269 return errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcPC: %s", jsonutils.Marshal(vpcPC).String()) 270 } 271 err = self.region.AcceptVpcPeering(id) 272 if err != nil { 273 return errors.Wrapf(err, "self.region.AcceptVpcPeering(%s)", id) 274 } 275 return nil 276 } 277 278 func (self *SVpc) GetAuthorityOwnerId() string { 279 return self.region.client.projectId 280 } 281 282 func (self *SVpc) getVpcPeeringConnections() ([]SVpcPeering, error) { 283 svpcPeerings, err := self.region.GetVpcPeerings(self.GetId()) 284 if err != nil { 285 return nil, errors.Wrapf(err, "self.region.GetVpcPeerings(%s)", self.GetId()) 286 } 287 vpcPCs := []SVpcPeering{} 288 for i := range svpcPeerings { 289 if svpcPeerings[i].GetVpcId() == self.GetId() { 290 svpcPeerings[i].vpc = self 291 vpcPCs = append(vpcPCs, svpcPeerings[i]) 292 } 293 } 294 return vpcPCs, nil 295 } 296 297 func (self *SVpc) getAccepterVpcPeeringConnections() ([]SVpcPeering, error) { 298 svpcPeerings, err := self.region.GetVpcPeerings(self.GetId()) 299 if err != nil { 300 return nil, errors.Wrapf(err, "self.region.GetVpcPeerings(%s)", self.GetId()) 301 } 302 vpcPCs := []SVpcPeering{} 303 for i := range svpcPeerings { 304 if svpcPeerings[i].GetPeerVpcId() == self.GetId() { 305 svpcPeerings[i].vpc = self 306 vpcPCs = append(vpcPCs, svpcPeerings[i]) 307 } 308 } 309 return vpcPCs, nil 310 } 311 312 func (self *SVpc) getVpcPeeringConnectionById(id string) (*SVpcPeering, error) { 313 svpcPC, err := self.region.GetVpcPeering(id) 314 if err != nil { 315 return nil, errors.Wrapf(err, "self.region.GetVpcPeering(%s)", id) 316 } 317 svpcPC.vpc = self 318 return svpcPC, nil 319 } 320 321 func (self *SRegion) getVpc(vpcId string) (*SVpc, error) { 322 vpc := SVpc{} 323 err := DoGet(self.ecsClient.Vpcs.Get, vpcId, nil, &vpc) 324 if err != nil && strings.Contains(err.Error(), "RouterNotFound") { 325 return nil, cloudprovider.ErrNotFound 326 } 327 vpc.region = self 328 return &vpc, err 329 } 330 331 func (self *SRegion) DeleteVpc(vpcId string) error { 332 if vpcId != "default" { 333 secgroups, err := self.GetSecurityGroups(vpcId, "") 334 if err != nil { 335 return errors.Wrap(err, "GetSecurityGroups") 336 } 337 for _, secgroup := range secgroups { 338 err = self.DeleteSecurityGroup(secgroup.ID) 339 if err != nil { 340 return errors.Wrapf(err, "DeleteSecurityGroup(%s)", secgroup.ID) 341 } 342 } 343 } 344 return DoDelete(self.ecsClient.Vpcs.Delete, vpcId, nil, nil) 345 } 346 347 // https://support.huaweicloud.com/api-vpc/zh-cn_topic_0020090625.html 348 func (self *SRegion) GetVpcs() ([]SVpc, error) { 349 querys := make(map[string]string) 350 351 vpcs := make([]SVpc, 0) 352 err := doListAllWithMarker(self.ecsClient.Vpcs.List, querys, &vpcs) 353 if err != nil { 354 return nil, err 355 } 356 357 for i := range vpcs { 358 vpcs[i].region = self 359 } 360 return vpcs, err 361 }