yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aws/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 aws 16 17 import ( 18 "fmt" 19 "strings" 20 "time" 21 22 "github.com/aws/aws-sdk-go/service/ec2" 23 24 "yunion.io/x/jsonutils" 25 "yunion.io/x/log" 26 "yunion.io/x/pkg/errors" 27 28 api "yunion.io/x/cloudmux/pkg/apis/compute" 29 "yunion.io/x/cloudmux/pkg/cloudprovider" 30 "yunion.io/x/cloudmux/pkg/multicloud" 31 ) 32 33 type SUserCIDRs struct { 34 UserCidr []string 35 } 36 37 type SVpc struct { 38 multicloud.SVpc 39 AwsTags 40 41 region *SRegion 42 43 iwires []cloudprovider.ICloudWire 44 secgroups []cloudprovider.ICloudSecurityGroup 45 46 RegionId string 47 VpcId string 48 VpcName string 49 CidrBlock string 50 CidrBlockAssociationSet []string 51 IsDefault bool 52 Status string 53 InstanceTenancy string 54 } 55 56 func (self *SVpc) addWire(wire *SWire) { 57 if self.iwires == nil { 58 self.iwires = make([]cloudprovider.ICloudWire, 0) 59 } 60 self.iwires = append(self.iwires, wire) 61 } 62 63 func (self *SVpc) GetId() string { 64 return self.VpcId 65 } 66 67 func (self *SVpc) GetName() string { 68 if len(self.VpcName) > 0 { 69 return self.VpcName 70 } 71 return self.VpcId 72 } 73 74 func (self *SVpc) GetGlobalId() string { 75 return self.VpcId 76 } 77 78 func (self *SVpc) GetStatus() string { 79 // 目前不支持专用主机 80 if self.InstanceTenancy == "dedicated" { 81 return api.VPC_STATUS_UNAVAILABLE 82 } 83 return strings.ToLower(self.Status) 84 } 85 86 func (self *SVpc) Refresh() error { 87 new, err := self.region.getVpc(self.VpcId) 88 if err != nil { 89 return err 90 } 91 return jsonutils.Update(self, new) 92 } 93 94 func (self *SVpc) IsEmulated() bool { 95 return false 96 } 97 98 func (self *SVpc) GetRegion() cloudprovider.ICloudRegion { 99 return self.region 100 } 101 102 func (self *SVpc) GetIsDefault() bool { 103 return self.IsDefault 104 } 105 106 func (self *SVpc) GetCidrBlock() string { 107 return strings.Join(self.CidrBlockAssociationSet, ",") 108 } 109 110 func (self *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) { 111 if self.iwires == nil { 112 err := self.fetchNetworks() 113 if err != nil { 114 return nil, errors.Wrap(err, "fetchNetworks") 115 } 116 } 117 return self.iwires, nil 118 } 119 120 func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) { 121 if self.secgroups == nil { 122 err := self.fetchSecurityGroups() 123 if err != nil { 124 return nil, errors.Wrap(err, "fetchSecurityGroups") 125 } 126 } 127 return self.secgroups, nil 128 } 129 130 func (self *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) { 131 tables, err := self.region.GetRouteTables(self.GetId(), false) 132 if err != nil { 133 return nil, errors.Wrap(err, "SVpc.GetIRouteTables") 134 } 135 136 itables := make([]cloudprovider.ICloudRouteTable, len(tables)) 137 for i := range tables { 138 tables[i].vpc = self 139 itables[i] = &tables[i] 140 } 141 142 return itables, nil 143 } 144 145 func (self *SVpc) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudRouteTable, error) { 146 routeTable, err := self.region.GetRouteTable(routeTableId) 147 if err != nil { 148 return nil, errors.Wrapf(err, "self.region.GetRouteTable(routeTableId:%s)", routeTableId) 149 } 150 routeTable.vpc = self 151 return routeTable, nil 152 } 153 154 /* 155 Deletes the specified VPC. You must detach or delete all gateways and resources that are associated with 156 the VPC before you can delete it. For example, you must terminate all instances running in the VPC, 157 delete all security groups associated with the VPC (except the default one), 158 delete all route tables associated with the VPC (except the default one), and so on. 159 */ 160 func (self *SVpc) Delete() error { 161 err := self.DeleteInternetGateways() 162 if err != nil { 163 return errors.Wrap(err, "DeleteInternetGateways") 164 } 165 166 // 删除路由表. todo: 3.7版本路由表开放之后,需要同步状态到平台 167 rts, err := self.GetIRouteTables() 168 if err != nil { 169 return errors.Wrap(err, "GetIRouteTables") 170 } 171 172 for i := range rts { 173 // 主路由表不允许删除 174 rt := rts[i].(*SRouteTable) 175 if len(rt.Associations) > 0 { 176 if rt.Associations[0].Main { 177 log.Debugf("Delete.RouteTable skipped main route table %s(%s)", rt.GetName(), rt.GetId()) 178 continue 179 } 180 } 181 182 err = self.region.DeleteRouteTable(rts[i].GetId()) 183 if err != nil { 184 return errors.Wrap(err, "DeleteRouteTable") 185 } 186 } 187 188 return self.region.DeleteVpc(self.VpcId) 189 } 190 191 func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) { 192 if self.iwires == nil { 193 err := self.fetchNetworks() 194 if err != nil { 195 return nil, errors.Wrap(err, "fetchNetworks") 196 } 197 } 198 for i := 0; i < len(self.iwires); i += 1 { 199 if self.iwires[i].GetGlobalId() == wireId { 200 return self.iwires[i], nil 201 } 202 } 203 return nil, errors.Wrap(cloudprovider.ErrNotFound, "GetIWireById") 204 } 205 206 func (self *SVpc) getWireByZoneId(zoneId string) *SWire { 207 for i := 0; i < len(self.iwires); i += 1 { 208 wire := self.iwires[i].(*SWire) 209 if wire.zone.ZoneId == zoneId { 210 return wire 211 } 212 } 213 214 zone, err := self.region.getZoneById(zoneId) 215 if err != nil { 216 return nil 217 } 218 return &SWire{ 219 zone: zone, 220 vpc: self, 221 } 222 } 223 224 func (self *SVpc) fetchNetworks() error { 225 networks, err := self.region.GetNetwroks(nil, self.VpcId) 226 if err != nil { 227 return errors.Wrapf(err, "GetNetwroks(%s)", self.VpcId) 228 } 229 230 for i := 0; i < len(networks); i += 1 { 231 wire := self.getWireByZoneId(networks[i].ZoneId) 232 networks[i].wire = wire 233 wire.addNetwork(&networks[i]) 234 } 235 return nil 236 } 237 238 func (self *SVpc) revokeSecurityGroup(secgroupId string, instanceId string, keep bool) error { 239 return self.region.revokeSecurityGroup(secgroupId, instanceId, keep) 240 } 241 242 func (self *SVpc) assignSecurityGroup(secgroupId string, instanceId string) error { 243 return self.region.assignSecurityGroup(secgroupId, instanceId) 244 } 245 246 func (self *SVpc) fetchSecurityGroups() error { 247 if len(self.VpcId) == 0 { 248 return fmt.Errorf("fetchSecurityGroups vpc id is empty") 249 } 250 251 secgroups, _, err := self.region.GetSecurityGroups(self.VpcId, "", "", 0, 0) 252 if err != nil { 253 return errors.Wrap(err, "GetSecurityGroups") 254 } 255 256 self.secgroups = make([]cloudprovider.ICloudSecurityGroup, len(secgroups)) 257 for i := 0; i < len(secgroups); i++ { 258 secgroups[i].vpc = self 259 self.secgroups[i] = &secgroups[i] 260 } 261 return nil 262 } 263 264 func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) { 265 svpcPCs, err := self.getRequesterVpcPeeringConnections() 266 if err != nil { 267 return nil, errors.Wrap(err, "self.getSVpcPeeringConnections()") 268 } 269 ret := []cloudprovider.ICloudVpcPeeringConnection{} 270 for i := range svpcPCs { 271 ret = append(ret, svpcPCs[i]) 272 } 273 return ret, nil 274 } 275 276 func (self *SVpc) GetICloudAccepterVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) { 277 svpcPCs, err := self.getAccepterVpcPeeringConnections() 278 if err != nil { 279 return nil, errors.Wrap(err, "self.getAccepterVpcPeeringConnections()") 280 } 281 ret := []cloudprovider.ICloudVpcPeeringConnection{} 282 for i := range svpcPCs { 283 ret = append(ret, svpcPCs[i]) 284 } 285 return ret, nil 286 } 287 288 func (self *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) { 289 vpcPc, err := self.getSVpcPeeringConnectionById(id) 290 if err != nil { 291 return nil, errors.Wrapf(err, "getSVpcPeeringConnectionById(%s)", id) 292 } 293 return vpcPc, nil 294 } 295 296 func (self *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) { 297 return self.createSVpcPeeringConnection(opts) 298 } 299 300 func (self *SVpc) AcceptICloudVpcPeeringConnection(id string) error { 301 return self.acceptSVpcPeeringConnection(id) 302 } 303 304 func (self *SVpc) GetAuthorityOwnerId() string { 305 identity, err := self.region.client.GetCallerIdentity() 306 if err != nil { 307 log.Errorf(err.Error() + "self.region.client.GetCallerIdentity()") 308 return "" 309 } 310 return identity.Account 311 } 312 313 func (self *SVpc) getSVpcPeeringConnectionById(id string) (*SVpcPeeringConnection, error) { 314 vpcPC, err := self.region.GetVpcPeeringConnectionById(id) 315 if err != nil { 316 return nil, errors.Wrapf(err, "self.region.GetVpcPeeringConnectionById(%s)", id) 317 } 318 if vpcPC.Status.Code != nil && (*vpcPC.Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleted || 319 *vpcPC.Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleting) { 320 return nil, cloudprovider.ErrNotFound 321 } 322 svpcPC := SVpcPeeringConnection{} 323 svpcPC.vpc = self 324 svpcPC.vpcPC = vpcPC 325 return &svpcPC, nil 326 } 327 328 func (self *SVpc) getRequesterVpcPeeringConnections() ([]*SVpcPeeringConnection, error) { 329 vpcPCs, err := self.region.DescribeRequesterVpcPeeringConnections(self.VpcId) 330 if err != nil { 331 return nil, errors.Wrap(err, "self.region.DescribeRequesterVpcPeeringConnections()") 332 } 333 ivpcPCs := []*SVpcPeeringConnection{} 334 for i := range vpcPCs { 335 if vpcPCs[i].Status.Code != nil && (*vpcPCs[i].Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleted || 336 *vpcPCs[i].Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleting) { 337 continue 338 } 339 svpcPC := SVpcPeeringConnection{} 340 svpcPC.vpc = self 341 svpcPC.vpcPC = vpcPCs[i] 342 ivpcPCs = append(ivpcPCs, &svpcPC) 343 } 344 return ivpcPCs, nil 345 } 346 347 func (self *SVpc) getAccepterVpcPeeringConnections() ([]*SVpcPeeringConnection, error) { 348 vpcPCs, err := self.region.DescribeAccepterVpcPeeringConnections(self.VpcId) 349 if err != nil { 350 return nil, errors.Wrap(err, "self.region.DescribeAccepterVpcPeeringConnections()") 351 } 352 ivpcPCs := []*SVpcPeeringConnection{} 353 for i := range vpcPCs { 354 if vpcPCs[i].Status.Code != nil && (*vpcPCs[i].Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleted || 355 *vpcPCs[i].Status.Code == ec2.VpcPeeringConnectionStateReasonCodeDeleting) { 356 continue 357 } 358 svpcPC := SVpcPeeringConnection{} 359 svpcPC.vpc = self 360 svpcPC.vpcPC = vpcPCs[i] 361 ivpcPCs = append(ivpcPCs, &svpcPC) 362 } 363 return ivpcPCs, nil 364 } 365 366 func (self *SVpc) createSVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (*SVpcPeeringConnection, error) { 367 svpcPC := SVpcPeeringConnection{} 368 vpcPC, err := self.region.CreateVpcPeeringConnection(self.VpcId, opts) 369 if err != nil { 370 return nil, errors.Wrapf(err, " self.region.CreateVpcPeeringConnection(%s,%s)", self.VpcId, jsonutils.Marshal(opts).String()) 371 } 372 svpcPC.vpc = self 373 svpcPC.vpcPC = vpcPC 374 err = cloudprovider.WaitMultiStatus(&svpcPC, []string{api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT, 375 api.VPC_PEERING_CONNECTION_STATUS_ACTIVE, 376 api.VPC_PEERING_CONNECTION_STATUS_DELETING}, 5*time.Second, 60*time.Second) 377 if err != nil { 378 return nil, errors.Wrap(err, "cloudprovider.WaitMultiStatus") 379 } 380 if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_DELETING { 381 return nil, errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcpeeringconnection:%s invalidate status", jsonutils.Marshal(svpcPC.vpcPC).String()) 382 } 383 return &svpcPC, nil 384 } 385 386 func (self *SVpc) acceptSVpcPeeringConnection(id string) error { 387 svpcPC, err := self.getSVpcPeeringConnectionById(id) 388 if err != nil { 389 return errors.Wrapf(err, "self.getSVpcPeeringConnectionById(%s)", id) 390 } 391 // 其他region 创建的连接请求,有短暂的provisioning状态 392 err = cloudprovider.WaitMultiStatus(svpcPC, []string{api.VPC_PEERING_CONNECTION_STATUS_ACTIVE, 393 api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT, 394 api.VPC_PEERING_CONNECTION_STATUS_DELETING}, 5*time.Second, 60*time.Second) 395 if err != nil { 396 return errors.Wrap(err, "cloudprovider.WaitMultiStatus") 397 } 398 if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_DELETING { 399 return errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcpeeringconnection:%s invalidate status", jsonutils.Marshal(svpcPC.vpcPC).String()) 400 } 401 402 if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT { 403 _, err := self.region.AcceptVpcPeeringConnection(id) 404 if err != nil { 405 return errors.Wrapf(err, "self.region.AcceptVpcPeeringConnection(%s)", id) 406 } 407 } 408 err = cloudprovider.WaitMultiStatus(svpcPC, []string{api.VPC_PEERING_CONNECTION_STATUS_ACTIVE, 409 api.VPC_PEERING_CONNECTION_STATUS_DELETING}, 5*time.Second, 60*time.Second) 410 if err != nil { 411 return errors.Wrap(err, "cloudprovider.WaitMultiStatus") 412 } 413 if svpcPC.GetStatus() == api.VPC_PEERING_CONNECTION_STATUS_DELETING { 414 return errors.Wrapf(cloudprovider.ErrInvalidStatus, "vpcpeeringconnection:%s invalidate status", jsonutils.Marshal(svpcPC.vpcPC).String()) 415 } 416 return nil 417 } 418 419 func (self *SVpc) IsSupportSetExternalAccess() bool { 420 return true 421 } 422 423 func (self *SVpc) GetExternalAccessMode() string { 424 igws, err := self.region.GetInternetGateways(self.GetId()) 425 if err != nil { 426 log.Errorf("GetExternalAccessMode.GetInternetGateways %s", err) 427 } 428 429 if len(igws) > 0 { 430 return api.VPC_EXTERNAL_ACCESS_MODE_EIP 431 } 432 433 return api.VPC_EXTERNAL_ACCESS_MODE_NONE 434 } 435 436 func (self *SVpc) AttachInternetGateway(igwId string) error { 437 ec2Client, err := self.region.getEc2Client() 438 if err != nil { 439 return errors.Wrap(err, "getEc2Client") 440 } 441 442 input := ec2.AttachInternetGatewayInput{} 443 input.SetInternetGatewayId(igwId) 444 input.SetVpcId(self.GetId()) 445 446 _, err = ec2Client.AttachInternetGateway(&input) 447 if err != nil { 448 return errors.Wrap(err, "AttachInternetGateway") 449 } 450 451 err = self.AddDefaultInternetGatewayRoute(igwId) 452 if err != nil { 453 return errors.Wrap(err, "AddDefaultInternetGatewayRoute") 454 } 455 456 return nil 457 } 458 459 func (self *SVpc) AddDefaultInternetGatewayRoute(igwId string) error { 460 rt, err := self.GetMainRouteTable() 461 if err != nil { 462 return errors.Wrap(err, "GetMainRouteTable") 463 } 464 465 defaultRoute := cloudprovider.RouteSet{} 466 defaultRoute.NextHop = igwId 467 defaultRoute.Destination = "0.0.0.0/0" 468 err = rt.CreateRoute(defaultRoute) 469 if err != nil { 470 return errors.Wrap(err, "CreateRoute") 471 } 472 473 return nil 474 } 475 476 func (self *SVpc) GetMainRouteTable() (*SRouteTable, error) { 477 rt, err := self.region.GetRouteTables(self.GetId(), true) 478 if err != nil { 479 return nil, errors.Wrap(err, "GetRouteTables") 480 } 481 482 if len(rt) == 0 { 483 return nil, errors.Wrap(cloudprovider.ErrNotSupported, "GetMainRouteTable") 484 } 485 486 return &rt[0], nil 487 } 488 489 func (self *SVpc) DetachInternetGateways() error { 490 igws, err := self.region.GetInternetGateways(self.GetId()) 491 if err != nil { 492 return errors.Wrap(err, "GetInternetGateways") 493 } 494 495 if len(igws) > 0 { 496 for i := range igws { 497 err = self.DetachInternetGateway(igws[i].GetId()) 498 if err != nil { 499 return errors.Wrap(err, "DetachInternetGateway") 500 } 501 } 502 } 503 504 return nil 505 } 506 507 func (self *SVpc) DetachInternetGateway(igwId string) error { 508 ec2Client, err := self.region.getEc2Client() 509 if err != nil { 510 return errors.Wrap(err, "getEc2Client") 511 } 512 513 input := ec2.DetachInternetGatewayInput{} 514 input.SetInternetGatewayId(igwId) 515 input.SetVpcId(self.GetId()) 516 517 _, err = ec2Client.DetachInternetGateway(&input) 518 if err != nil { 519 return errors.Wrap(err, "DetachInternetGateway") 520 } 521 522 return nil 523 } 524 525 func (self *SVpc) DeleteInternetGateway(igwId string) error { 526 ec2Client, err := self.region.getEc2Client() 527 if err != nil { 528 return errors.Wrap(err, "getEc2Client") 529 } 530 531 input := ec2.DeleteInternetGatewayInput{} 532 input.SetInternetGatewayId(igwId) 533 534 _, err = ec2Client.DeleteInternetGateway(&input) 535 if err != nil { 536 return errors.Wrap(err, "DeleteInternetGateway") 537 } 538 539 return nil 540 } 541 542 func (self *SVpc) DeleteInternetGateways() error { 543 igws, err := self.region.GetInternetGateways(self.GetId()) 544 if err != nil { 545 return errors.Wrap(err, "GetInternetGateways") 546 } 547 548 if len(igws) > 0 { 549 for i := range igws { 550 err = self.DetachInternetGateway(igws[i].GetId()) 551 if err != nil { 552 return errors.Wrap(err, "DetachInternetGateway") 553 } 554 555 err = self.DeleteInternetGateway(igws[i].GetId()) 556 if err != nil { 557 return errors.Wrap(err, "DeleteInternetGateway") 558 } 559 } 560 } 561 562 return nil 563 } 564 565 func (self *SRegion) getVpc(vpcId string) (*SVpc, error) { 566 if len(vpcId) == 0 { 567 return nil, fmt.Errorf("GetVpc vpc id should not be empty.") 568 } 569 570 vpcs, err := self.GetVpcs([]string{vpcId}) 571 if err != nil { 572 return nil, errors.Wrap(err, "GetVpcs") 573 } 574 if len(vpcs) != 1 { 575 return nil, errors.Wrap(cloudprovider.ErrNotFound, "getVpc") 576 } 577 vpcs[0].region = self 578 return &vpcs[0], nil 579 } 580 581 func (self *SRegion) revokeSecurityGroup(secgroupId, instanceId string, keep bool) error { 582 // todo : keep ? 直接使用assignSecurityGroup 即可? 583 return nil 584 } 585 586 func (self *SRegion) assignSecurityGroup(secgroupId, instanceId string) error { 587 return self.assignSecurityGroups([]*string{&secgroupId}, instanceId) 588 } 589 590 func (self *SRegion) assignSecurityGroups(secgroupIds []*string, instanceId string) error { 591 instance, err := self.GetInstance(instanceId) 592 if err != nil { 593 return errors.Wrap(err, "GetInstance") 594 } 595 596 ec2Client, err := self.getEc2Client() 597 if err != nil { 598 return errors.Wrap(err, "getEc2Client") 599 } 600 601 for _, eth := range instance.NetworkInterfaces { 602 params := &ec2.ModifyNetworkInterfaceAttributeInput{} 603 params.SetNetworkInterfaceId(eth.NetworkInterfaceId) 604 params.SetGroups(secgroupIds) 605 606 _, err := ec2Client.ModifyNetworkInterfaceAttribute(params) 607 if err != nil { 608 return err 609 } 610 } 611 612 return nil 613 } 614 615 func (self *SRegion) DeleteSecurityGroup(secGrpId string) error { 616 ec2Client, err := self.getEc2Client() 617 if err != nil { 618 return errors.Wrap(err, "getEc2Client") 619 } 620 621 params := &ec2.DeleteSecurityGroupInput{} 622 params.SetGroupId(secGrpId) 623 624 _, err = ec2Client.DeleteSecurityGroup(params) 625 return errors.Wrap(err, "DeleteSecurityGroup") 626 } 627 628 func (self *SRegion) DeleteVpc(vpcId string) error { 629 ec2Client, err := self.getEc2Client() 630 if err != nil { 631 return errors.Wrap(err, "getEc2Client") 632 } 633 634 params := &ec2.DeleteVpcInput{} 635 params.SetVpcId(vpcId) 636 637 _, err = ec2Client.DeleteVpc(params) 638 return errors.Wrap(err, "DeleteVpc") 639 } 640 641 func (self *SRegion) GetVpcs(vpcId []string) ([]SVpc, error) { 642 ec2Client, err := self.getEc2Client() 643 if err != nil { 644 return nil, errors.Wrap(err, "getEc2Client") 645 } 646 647 params := &ec2.DescribeVpcsInput{} 648 if len(vpcId) > 0 { 649 params.SetVpcIds(ConvertedList(vpcId)) 650 } 651 652 ret, err := ec2Client.DescribeVpcs(params) 653 err = parseNotFoundError(err) 654 if err != nil { 655 return nil, err 656 } 657 658 vpcs := []SVpc{} 659 for _, item := range ret.Vpcs { 660 if err := FillZero(item); err != nil { 661 return nil, err 662 } 663 cidrBlockAssociationSet := []string{} 664 for i := range item.CidrBlockAssociationSet { 665 cidr := item.CidrBlockAssociationSet[i] 666 if cidr.CidrBlockState.State != nil && *cidr.CidrBlockState.State == "associated" { 667 cidrBlockAssociationSet = append(cidrBlockAssociationSet, *cidr.CidrBlock) 668 } 669 } 670 671 tagspec := TagSpec{ResourceType: "vpc"} 672 tagspec.LoadingEc2Tags(item.Tags) 673 674 vpc := SVpc{ 675 region: self, 676 RegionId: self.RegionId, 677 VpcId: *item.VpcId, 678 VpcName: tagspec.GetNameTag(), 679 CidrBlock: *item.CidrBlock, 680 CidrBlockAssociationSet: cidrBlockAssociationSet, 681 IsDefault: *item.IsDefault, 682 Status: *item.State, 683 InstanceTenancy: *item.InstanceTenancy, 684 } 685 jsonutils.Update(&vpc.AwsTags.TagSet, item.Tags) 686 vpcs = append(vpcs, vpc) 687 } 688 689 return vpcs, nil 690 } 691 692 func (self *SRegion) GetInternetGateways(vpcId string) ([]SInternetGateway, error) { 693 ec2Client, err := self.getEc2Client() 694 if err != nil { 695 return nil, errors.Wrap(err, "getEc2Client") 696 } 697 698 input := ec2.DescribeInternetGatewaysInput{} 699 filters := make([]*ec2.Filter, 0) 700 if len(vpcId) > 0 { 701 filters = AppendSingleValueFilter(filters, "attachment.vpc-id", vpcId) 702 } 703 704 if len(filters) > 0 { 705 input.SetFilters(filters) 706 } 707 output, err := ec2Client.DescribeInternetGateways(&input) 708 if err != nil { 709 return nil, errors.Wrap(err, "DescribeInternetGateways") 710 } 711 712 igws := make([]SInternetGateway, len(output.InternetGateways)) 713 err = unmarshalAwsOutput(output, "InternetGateways", &igws) 714 if err != nil { 715 return nil, errors.Wrap(err, "unmarshalAwsOutput") 716 } 717 718 for i := range igws { 719 igws[i].region = self 720 } 721 722 return igws, nil 723 }