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