| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package aws
- import (
- "fmt"
- "strings"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/utils"
- api "yunion.io/x/cloudmux/pkg/apis/compute"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/cloudmux/pkg/multicloud"
- )
- type SUserCIDRs struct {
- UserCidr []string
- }
- type SVpc struct {
- multicloud.SVpc
- AwsTags
- region *SRegion
- VpcId string `xml:"vpcId"`
- CidrBlock string `xml:"cidrBlock"`
- CidrBlockAssociationSet []struct {
- CidrBlock string `xml:"cidrBlock"`
- AssociationId string `xml:"associationId"`
- CidrBlockState struct {
- State string `xml:"state"`
- } `xml:"cidrBlockState"`
- } `xml:"cidrBlockAssociationSet>item"`
- IPv6CidrBlockAssociationSet []struct {
- IPv6CidrBlock string `xml:"ipv6CidrBlock"`
- } `xml:"ipv6CidrBlockAssociationSet>item"`
- IsDefault bool `xml:"isDefault"`
- Status string `xml:"state"`
- InstanceTenancy string `xml:"instanceTenancy"`
- }
- func (self *SVpc) GetId() string {
- return self.VpcId
- }
- func (self *SVpc) GetName() string {
- name := self.AwsTags.GetName()
- if len(name) > 0 {
- return name
- }
- return self.VpcId
- }
- func (self *SVpc) GetGlobalId() string {
- return self.VpcId
- }
- func (self *SVpc) GetStatus() string {
- // 目前不支持专用主机
- if self.InstanceTenancy == "dedicated" {
- return api.VPC_STATUS_UNAVAILABLE
- }
- // pending | available
- return strings.ToLower(self.Status)
- }
- func (self *SVpc) Refresh() error {
- new, err := self.region.getVpc(self.VpcId)
- if err != nil {
- return err
- }
- return jsonutils.Update(self, new)
- }
- func (self *SVpc) GetRegion() cloudprovider.ICloudRegion {
- return self.region
- }
- func (self *SVpc) GetIsDefault() bool {
- return self.IsDefault
- }
- func (self *SVpc) GetCidrBlock() string {
- cidr := []string{self.CidrBlock}
- for _, ip := range self.CidrBlockAssociationSet {
- if !utils.IsInStringArray(ip.CidrBlock, cidr) {
- cidr = append(cidr, ip.CidrBlock)
- }
- }
- return strings.Join(cidr, ",")
- }
- func (self *SVpc) GetCidrBlock6() string {
- ret := []string{}
- for _, cidr := range self.IPv6CidrBlockAssociationSet {
- if len(cidr.IPv6CidrBlock) > 0 {
- ret = append(ret, cidr.IPv6CidrBlock)
- }
- }
- return strings.Join(ret, ",")
- }
- func (self *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) {
- zones, err := self.region.GetZones("")
- if err != nil {
- return nil, err
- }
- ret := []cloudprovider.ICloudWire{}
- for i := range zones {
- zones[i].region = self.region
- ret = append(ret, &SWire{zone: &zones[i], vpc: self})
- }
- return ret, nil
- }
- func (self *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
- secgroups, err := self.region.GetSecurityGroups(self.VpcId, "", "")
- if err != nil {
- return nil, errors.Wrap(err, "GetSecurityGroups")
- }
- ret := []cloudprovider.ICloudSecurityGroup{}
- for i := range secgroups {
- secgroups[i].region = self.region
- ret = append(ret, &secgroups[i])
- }
- return ret, nil
- }
- func (self *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
- tables, err := self.region.GetRouteTables(self.GetId(), "", "", "", false)
- if err != nil {
- return nil, errors.Wrap(err, "SVpc.GetIRouteTables")
- }
- itables := make([]cloudprovider.ICloudRouteTable, len(tables))
- for i := range tables {
- tables[i].vpc = self
- itables[i] = &tables[i]
- }
- return itables, nil
- }
- func (self *SVpc) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudRouteTable, error) {
- routeTable, err := self.region.GetRouteTable(routeTableId)
- if err != nil {
- return nil, errors.Wrapf(err, "self.region.GetRouteTable(routeTableId:%s)", routeTableId)
- }
- routeTable.vpc = self
- return routeTable, nil
- }
- /*
- Deletes the specified VPC. You must detach or delete all gateways and resources that are associated with
- the VPC before you can delete it. For example, you must terminate all instances running in the VPC,
- delete all security groups associated with the VPC (except the default one),
- delete all route tables associated with the VPC (except the default one), and so on.
- */
- func (self *SVpc) Delete() error {
- err := self.DeleteInternetGateways()
- if err != nil {
- return errors.Wrap(err, "DeleteInternetGateways")
- }
- // 删除路由表. todo: 3.7版本路由表开放之后,需要同步状态到平台
- rts, err := self.GetIRouteTables()
- if err != nil {
- return errors.Wrap(err, "GetIRouteTables")
- }
- for i := range rts {
- // 主路由表不允许删除
- rt := rts[i].(*SRouteTable)
- if len(rt.Associations) > 0 {
- if rt.Associations[0].Main {
- log.Debugf("Delete.RouteTable skipped main route table %s(%s)", rt.GetName(), rt.GetId())
- continue
- }
- }
- err = self.region.DeleteRouteTable(rts[i].GetId())
- if err != nil {
- return errors.Wrap(err, "DeleteRouteTable")
- }
- }
- return self.region.DeleteVpc(self.VpcId)
- }
- func (self *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) {
- wires, err := self.GetIWires()
- if err != nil {
- return nil, err
- }
- for i := range wires {
- if wires[i].GetGlobalId() == wireId {
- return wires[i], nil
- }
- }
- return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", wireId)
- }
- func (self *SVpc) GetICloudVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) {
- peers, err := self.region.DescribeVpcPeeringConnections("", self.VpcId, "")
- if err != nil {
- return nil, err
- }
- ret := []cloudprovider.ICloudVpcPeeringConnection{}
- for i := range peers {
- peers[i].vpc = self
- ret = append(ret, &peers[i])
- }
- return ret, nil
- }
- func (self *SVpc) GetICloudAccepterVpcPeeringConnections() ([]cloudprovider.ICloudVpcPeeringConnection, error) {
- peers, err := self.region.DescribeVpcPeeringConnections("", "", self.VpcId)
- if err != nil {
- return nil, err
- }
- ret := []cloudprovider.ICloudVpcPeeringConnection{}
- for i := range peers {
- peers[i].vpc = self
- ret = append(ret, &peers[i])
- }
- return ret, nil
- }
- func (self *SVpc) GetICloudVpcPeeringConnectionById(id string) (cloudprovider.ICloudVpcPeeringConnection, error) {
- peer, err := self.region.GetVpcPeeringConnectionById(id)
- if err != nil {
- return nil, err
- }
- peer.vpc = self
- return peer, nil
- }
- func (self *SVpc) CreateICloudVpcPeeringConnection(opts *cloudprovider.VpcPeeringConnectionCreateOptions) (cloudprovider.ICloudVpcPeeringConnection, error) {
- peer, err := self.region.CreateVpcPeeringConnection(self.VpcId, opts)
- if err != nil {
- return nil, errors.Wrapf(err, "CreateVpcPeeringConnection")
- }
- peer.vpc = self
- return peer, nil
- }
- func (self *SVpc) AcceptICloudVpcPeeringConnection(id string) error {
- _, err := self.region.AcceptVpcPeeringConnection(id)
- return errors.Wrapf(err, "AcceptVpcPeeringConnection")
- }
- func (self *SVpc) GetAuthorityOwnerId() string {
- identity, err := self.region.client.GetCallerIdentity()
- if err != nil {
- log.Errorf("GetCallerIdentity error: %v", err)
- return ""
- }
- return identity.Account
- }
- func (self *SVpc) IsSupportSetExternalAccess() bool {
- return true
- }
- func (self *SVpc) GetExternalAccessMode() string {
- igws, err := self.region.GetInternetGateways(self.GetId())
- if err != nil {
- log.Errorf("GetExternalAccessMode.GetInternetGateways %s", err)
- }
- if len(igws) > 0 {
- return api.VPC_EXTERNAL_ACCESS_MODE_EIP
- }
- return api.VPC_EXTERNAL_ACCESS_MODE_NONE
- }
- func (self *SVpc) AttachInternetGateway(igwId string) error {
- params := map[string]string{
- "InternetGatewayId": igwId,
- "VpcId": self.VpcId,
- }
- ret := struct{}{}
- err := self.region.ec2Request("AttachInternetGateway", params, &ret)
- if err != nil {
- return errors.Wrapf(err, "AttachInternetGateway")
- }
- return self.AddDefaultInternetGatewayRoute(igwId)
- }
- func (self *SVpc) AddDefaultInternetGatewayRoute(igwId string) error {
- rt, err := self.GetMainRouteTable()
- if err != nil {
- return errors.Wrap(err, "GetMainRouteTable")
- }
- return self.region.CreateRoute(rt.RouteTableId, "0.0.0.0/0", igwId)
- }
- func (self *SVpc) GetMainRouteTable() (*SRouteTable, error) {
- rt, err := self.region.GetRouteTables(self.GetId(), "", "", "", true)
- if err != nil {
- return nil, errors.Wrap(err, "GetRouteTables")
- }
- if len(rt) == 0 {
- return nil, errors.Wrap(cloudprovider.ErrNotSupported, "GetMainRouteTable")
- }
- return &rt[0], nil
- }
- func (self *SVpc) DetachInternetGateways() error {
- igws, err := self.region.GetInternetGateways(self.GetId())
- if err != nil {
- return errors.Wrap(err, "GetInternetGateways")
- }
- if len(igws) > 0 {
- for i := range igws {
- err = self.region.DetachInternetGateway(self.VpcId, igws[i].GetId())
- if err != nil {
- return errors.Wrap(err, "DetachInternetGateway")
- }
- }
- }
- return nil
- }
- func (self *SRegion) DetachInternetGateway(vpcId, igwId string) error {
- params := map[string]string{
- "InternetGatewayId": igwId,
- "VpcId": vpcId,
- }
- ret := struct{}{}
- return self.ec2Request("DetachInternetGateway", params, &ret)
- }
- func (self *SRegion) DeleteInternetGateway(id string) error {
- params := map[string]string{
- "InternetGatewayId": id,
- }
- ret := struct{}{}
- return self.ec2Request("DeleteInternetGateway", params, &ret)
- }
- func (self *SVpc) DeleteInternetGateways() error {
- igws, err := self.region.GetInternetGateways(self.GetId())
- if err != nil {
- return errors.Wrap(err, "GetInternetGateways")
- }
- for i := range igws {
- err = self.region.DetachInternetGateway(self.VpcId, igws[i].GetId())
- if err != nil {
- return errors.Wrap(err, "DetachInternetGateway")
- }
- err = self.region.DeleteInternetGateway(igws[i].GetId())
- if err != nil {
- return errors.Wrap(err, "DeleteInternetGateway")
- }
- }
- return nil
- }
- func (self *SRegion) getVpc(vpcId string) (*SVpc, error) {
- vpcs, err := self.GetVpcs([]string{vpcId})
- if err != nil {
- return nil, errors.Wrap(err, "GetVpcs")
- }
- for i := range vpcs {
- if vpcs[i].VpcId == vpcId {
- vpcs[i].region = self
- return &vpcs[i], nil
- }
- }
- return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", vpcId)
- }
- func (self *SRegion) assignSecurityGroups(secgroupIds []string, instanceId string) error {
- instance, err := self.GetInstance(instanceId)
- if err != nil {
- return errors.Wrap(err, "GetInstance")
- }
- for _, eth := range instance.NetworkInterfaces {
- params := map[string]string{
- "NetworkInterfaceId": eth.NetworkInterfaceId,
- }
- for i, groupId := range secgroupIds {
- params[fmt.Sprintf("SecurityGroupId.%d", i+1)] = groupId
- }
- ret := struct{}{}
- err = self.ec2Request("ModifyNetworkInterfaceAttribute", params, &ret)
- if err != nil {
- return errors.Wrapf(err, "ModifyNetworkInterfaceAttribute")
- }
- }
- return nil
- }
- func (self *SRegion) DeleteSecurityGroup(id string) error {
- params := map[string]string{
- "GroupId": id,
- }
- ret := struct{}{}
- return self.ec2Request("DeleteSecurityGroup", params, &ret)
- }
- func (self *SRegion) DeleteVpc(vpcId string) error {
- params := map[string]string{
- "VpcId": vpcId,
- }
- ret := struct{}{}
- return self.ec2Request("DeleteVpc", params, &ret)
- }
- func (self *SRegion) GetVpcs(vpcIds []string) ([]SVpc, error) {
- params := map[string]string{}
- for i, id := range vpcIds {
- params[fmt.Sprintf("VpcId.%d", i+1)] = id
- }
- ret := []SVpc{}
- for {
- part := struct {
- NextToken string `xml:"nextToken"`
- VpcSet []SVpc `xml:"vpcSet>item"`
- }{}
- err := self.ec2Request("DescribeVpcs", params, &part)
- if err != nil {
- return nil, err
- }
- ret = append(ret, part.VpcSet...)
- if len(part.NextToken) == 0 || len(part.VpcSet) == 0 {
- break
- }
- params["NextToken"] = part.NextToken
- }
- return ret, nil
- }
- func (self *SRegion) GetInternetGateways(vpcId string) ([]SInternetGateway, error) {
- params := map[string]string{}
- idx := 1
- if len(vpcId) > 0 {
- params[fmt.Sprintf("Filter.%d.Name", idx)] = "attachment.vpc-id"
- params[fmt.Sprintf("Filter.%d.Value", idx)] = vpcId
- idx++
- }
- ret := []SInternetGateway{}
- for {
- part := struct {
- NextToken string `xml:"nextToken"`
- InternetGatewaySet []SInternetGateway `xml:"internetGatewaySet>item"`
- }{}
- err := self.ec2Request("DescribeInternetGateways", params, &part)
- if err != nil {
- return nil, errors.Wrapf(err, "DescribeInternetGateways")
- }
- ret = append(ret, part.InternetGatewaySet...)
- if len(part.NextToken) == 0 || len(part.InternetGatewaySet) == 0 {
- break
- }
- params["NextToken"] = part.NextToken
- }
- return ret, nil
- }
|