yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aws/vpc_peering_connection.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  	"github.com/aws/aws-sdk-go/service/ec2"
    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  func (self *SRegion) DescribeVpcPeeringConnections(vpcId string) ([]*ec2.VpcPeeringConnection, error) {
    29  	result := []*ec2.VpcPeeringConnection{}
    30  	requestvpcPCs, err := self.DescribeRequesterVpcPeeringConnections(vpcId)
    31  	if err != nil {
    32  		return nil, errors.Wrapf(err, "self.DescribeRequesterVpcPeeringConnections(%s)", vpcId)
    33  	}
    34  	result = append(result, requestvpcPCs...)
    35  	acceptvpcPCs, err := self.DescribeAccepterVpcPeeringConnections(vpcId)
    36  	if err != nil {
    37  		return nil, errors.Wrapf(err, "self.DescribeRequesterVpcPeeringConnections(%s)", vpcId)
    38  	}
    39  	result = append(result, acceptvpcPCs...)
    40  	return result, nil
    41  }
    42  
    43  func (self *SRegion) DescribeRequesterVpcPeeringConnections(vpcId string) ([]*ec2.VpcPeeringConnection, error) {
    44  	ec2Client, err := self.getEc2Client()
    45  	if err != nil {
    46  		return nil, errors.Wrap(err, "getEc2Client")
    47  	}
    48  
    49  	params := ec2.DescribeVpcPeeringConnectionsInput{}
    50  	result := []*ec2.VpcPeeringConnection{}
    51  	var maxResult int64 = 20
    52  	params.MaxResults = &maxResult
    53  	filter := ec2.Filter{}
    54  	filter.Values = []*string{&vpcId}
    55  	// request peeringConnection
    56  	filterName := "requester-vpc-info.vpc-id"
    57  
    58  	filter.Name = &filterName
    59  	params.Filters = []*ec2.Filter{&filter}
    60  	for {
    61  		ret, err := ec2Client.DescribeVpcPeeringConnections(&params)
    62  		if err != nil {
    63  			return nil, errors.Wrapf(err, "self.ec2Client.DescribeVpcPeeringConnections(%s)", jsonutils.Marshal(params).String())
    64  		}
    65  		result = append(result, ret.VpcPeeringConnections...)
    66  		if ret.NextToken == nil {
    67  			break
    68  		}
    69  		params.NextToken = ret.NextToken
    70  	}
    71  	return result, nil
    72  }
    73  
    74  func (self *SRegion) DescribeAccepterVpcPeeringConnections(vpcId string) ([]*ec2.VpcPeeringConnection, error) {
    75  	ec2Client, err := self.getEc2Client()
    76  	if err != nil {
    77  		return nil, errors.Wrap(err, "getEc2Client")
    78  	}
    79  
    80  	params := ec2.DescribeVpcPeeringConnectionsInput{}
    81  	result := []*ec2.VpcPeeringConnection{}
    82  	var maxResult int64 = 20
    83  	params.MaxResults = &maxResult
    84  	filter := ec2.Filter{}
    85  	filter.Values = []*string{&vpcId}
    86  	// accept peeringConnection
    87  	filterName := "accepter-vpc-info.vpc-id"
    88  	filter.Name = &filterName
    89  	params.Filters = []*ec2.Filter{&filter}
    90  	for {
    91  		ret, err := ec2Client.DescribeVpcPeeringConnections(&params)
    92  		if err != nil {
    93  			return nil, errors.Wrapf(err, "self.ec2Client.DescribeVpcPeeringConnections(%s)", jsonutils.Marshal(params).String())
    94  		}
    95  		result = append(result, ret.VpcPeeringConnections...)
    96  		if ret.NextToken == nil {
    97  			break
    98  		}
    99  		params.NextToken = ret.NextToken
   100  	}
   101  	return result, nil
   102  }
   103  
   104  func (self *SRegion) GetVpcPeeringConnectionById(Id string) (*ec2.VpcPeeringConnection, error) {
   105  	ec2Client, err := self.getEc2Client()
   106  	if err != nil {
   107  		return nil, errors.Wrap(err, "getEc2Client")
   108  	}
   109  
   110  	params := ec2.DescribeVpcPeeringConnectionsInput{}
   111  	result := []*ec2.VpcPeeringConnection{}
   112  	var maxResult int64 = 20
   113  	params.MaxResults = &maxResult
   114  	filter := ec2.Filter{}
   115  	filter.Values = []*string{&Id}
   116  	filterName := "vpc-peering-connection-id"
   117  	filter.Name = &filterName
   118  	params.Filters = []*ec2.Filter{&filter}
   119  	for {
   120  		ret, err := ec2Client.DescribeVpcPeeringConnections(&params)
   121  		if err != nil {
   122  			return nil, errors.Wrapf(err, "self.ec2Client.DescribeVpcPeeringConnections(%s)", jsonutils.Marshal(params).String())
   123  		}
   124  		result = append(result, ret.VpcPeeringConnections...)
   125  		if ret.NextToken == nil {
   126  			break
   127  		}
   128  		params.NextToken = ret.NextToken
   129  	}
   130  	if len(result) < 1 {
   131  		return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetVpcPeeringConnectionById(%s)", Id)
   132  	}
   133  	if len(result) > 1 {
   134  		return nil, errors.Wrapf(cloudprovider.ErrDuplicateId, "GetVpcPeeringConnectionById(%s)", Id)
   135  	}
   136  	return result[0], nil
   137  }
   138  
   139  func (self *SRegion) CreateVpcPeeringConnection(vpcId string, opts *cloudprovider.VpcPeeringConnectionCreateOptions) (*ec2.VpcPeeringConnection, error) {
   140  	ec2Client, err := self.getEc2Client()
   141  	if err != nil {
   142  		return nil, errors.Wrap(err, "getEc2Client")
   143  	}
   144  
   145  	params := ec2.CreateVpcPeeringConnectionInput{}
   146  	params.VpcId = &vpcId
   147  	params.PeerVpcId = &opts.PeerVpcId
   148  	params.PeerRegion = &opts.PeerRegionId
   149  	params.PeerOwnerId = &opts.PeerAccountId
   150  	ret, err := ec2Client.CreateVpcPeeringConnection(&params)
   151  	if err != nil {
   152  		return nil, errors.Wrapf(err, "self.ec2Client.CreateVpcPeeringConnection(%s)", jsonutils.Marshal(params).String())
   153  	}
   154  	// add tags
   155  	tagParams := ec2.CreateTagsInput{}
   156  	tagParams.Resources = []*string{ret.VpcPeeringConnection.VpcPeeringConnectionId}
   157  	nametag := "Name"
   158  	desctag := "Description"
   159  	tagParams.Tags = []*ec2.Tag{{Key: &nametag, Value: &opts.Name}, {Key: &desctag, Value: &opts.Desc}}
   160  	_, err = ec2Client.CreateTags(&tagParams)
   161  	if err != nil {
   162  		return nil, errors.Wrapf(err, "self.ec2Client.CreateTags(%s)", jsonutils.Marshal(tagParams).String())
   163  	}
   164  	ret.VpcPeeringConnection.Tags = tagParams.Tags
   165  	return ret.VpcPeeringConnection, nil
   166  }
   167  
   168  func (self *SRegion) DeleteVpcPeeringConnection(vpcPeeringConnectionId string) error {
   169  	ec2Client, err := self.getEc2Client()
   170  	if err != nil {
   171  		return errors.Wrap(err, "getEc2Client")
   172  	}
   173  
   174  	params := ec2.DeleteVpcPeeringConnectionInput{}
   175  	params.VpcPeeringConnectionId = &vpcPeeringConnectionId
   176  	_, err = ec2Client.DeleteVpcPeeringConnection(&params)
   177  	if err != nil {
   178  		return errors.Wrapf(err, "self.ec2Client.DeleteVpcPeeringConnection(%s)", jsonutils.Marshal(params).String())
   179  	}
   180  	return nil
   181  }
   182  
   183  func (self *SRegion) AcceptVpcPeeringConnection(vpcPeeringConnectionId string) (*ec2.VpcPeeringConnection, error) {
   184  	ec2Client, err := self.getEc2Client()
   185  	if err != nil {
   186  		return nil, errors.Wrap(err, "getEc2Client")
   187  	}
   188  
   189  	params := ec2.AcceptVpcPeeringConnectionInput{}
   190  	params.VpcPeeringConnectionId = &vpcPeeringConnectionId
   191  	ret, err := ec2Client.AcceptVpcPeeringConnection(&params)
   192  	if err != nil {
   193  		return nil, errors.Wrapf(err, "self.ec2Client.AcceptVpcPeeringConnection(%s)", jsonutils.Marshal(params).String())
   194  	}
   195  	return ret.VpcPeeringConnection, nil
   196  }
   197  
   198  func (self *SRegion) DeleteVpcPeeringConnectionRoute(vpcPeeringConnectionId string) error {
   199  	ec2Client, err := self.getEc2Client()
   200  	if err != nil {
   201  		return errors.Wrap(err, "getEc2Client")
   202  	}
   203  
   204  	input := &ec2.DescribeRouteTablesInput{}
   205  	filters := make([]*ec2.Filter, 0)
   206  	filters = AppendSingleValueFilter(filters, "association.main", "true")
   207  	filters = AppendSingleValueFilter(filters, "route.vpc-peering-connection-id", vpcPeeringConnectionId)
   208  	input.SetFilters(filters)
   209  	routeTables := []*ec2.RouteTable{}
   210  	for {
   211  		ret, err := ec2Client.DescribeRouteTables(input)
   212  		if err != nil {
   213  			return errors.Wrap(err, "SRegion.GetRouteTables.DescribeRouteTables")
   214  		}
   215  		routeTables = append(routeTables, ret.RouteTables...)
   216  		input.NextToken = ret.NextToken
   217  		if ret.NextToken == nil {
   218  			break
   219  		}
   220  	}
   221  	for i := range routeTables {
   222  		if routeTables[i] != nil && routeTables[i].RouteTableId != nil && routeTables[i].Routes != nil {
   223  			for j := range routeTables[i].Routes {
   224  				if routeTables[i].Routes[j] != nil &&
   225  					routeTables[i].Routes[j].VpcPeeringConnectionId != nil &&
   226  					*routeTables[i].Routes[j].VpcPeeringConnectionId == vpcPeeringConnectionId &&
   227  					routeTables[i].Routes[j].DestinationCidrBlock != nil {
   228  					err := self.RemoveRoute(*routeTables[i].RouteTableId, *routeTables[i].Routes[j].DestinationCidrBlock)
   229  					if err != nil {
   230  						return errors.Wrapf(err, "self.RemoveRoute(%s,%s)", *routeTables[i].RouteTableId, *routeTables[i].Routes[j].DestinationCidrBlock)
   231  					}
   232  				}
   233  			}
   234  		}
   235  	}
   236  	return nil
   237  }
   238  
   239  type SVpcPeeringConnection struct {
   240  	multicloud.SResourceBase
   241  	AwsTags
   242  	vpc   *SVpc
   243  	vpcPC *ec2.VpcPeeringConnection
   244  }
   245  
   246  func (self *SVpcPeeringConnection) GetId() string {
   247  	if self.vpcPC.VpcPeeringConnectionId != nil {
   248  		return *self.vpcPC.VpcPeeringConnectionId
   249  	}
   250  	return ""
   251  }
   252  
   253  // tags?
   254  func (self *SVpcPeeringConnection) GetName() string {
   255  	for i := range self.vpcPC.Tags {
   256  		if self.vpcPC.Tags[i] != nil && self.vpcPC.Tags[i].Key != nil &&
   257  			*self.vpcPC.Tags[i].Key == "Name" && self.vpcPC.Tags[i].Value != nil {
   258  			return *self.vpcPC.Tags[i].Value
   259  		}
   260  	}
   261  	return self.GetId()
   262  }
   263  
   264  func (self *SVpcPeeringConnection) GetGlobalId() string {
   265  	return self.GetId()
   266  }
   267  
   268  func (self *SVpcPeeringConnection) GetStatus() string {
   269  	if self.vpcPC.Status.Code != nil {
   270  		switch *self.vpcPC.Status.Code {
   271  		case ec2.VpcPeeringConnectionStateReasonCodeInitiatingRequest, ec2.VpcPeeringConnectionStateReasonCodeProvisioning:
   272  			return api.VPC_PEERING_CONNECTION_STATUS_CREATING
   273  		case ec2.VpcPeeringConnectionStateReasonCodePendingAcceptance:
   274  			return api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT
   275  		case ec2.VpcPeeringConnectionStateReasonCodeActive:
   276  			return api.VPC_PEERING_CONNECTION_STATUS_ACTIVE
   277  		case ec2.VpcPeeringConnectionStateReasonCodeDeleted, ec2.VpcPeeringConnectionStateReasonCodeDeleting:
   278  			return api.VPC_PEERING_CONNECTION_STATUS_DELETING
   279  		default:
   280  			return api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN
   281  		}
   282  	}
   283  	return api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN
   284  }
   285  
   286  func (self *SVpcPeeringConnection) Refresh() error {
   287  	vpcPC, err := self.vpc.region.GetVpcPeeringConnectionById(self.GetId())
   288  	if err != nil {
   289  		return errors.Wrapf(err, "self.vpc.region.GetVpcPeeringConnectionById(%s)", self.GetId())
   290  	}
   291  	self.vpcPC = vpcPC
   292  	return nil
   293  }
   294  
   295  func (self *SVpcPeeringConnection) GetPeerVpcId() string {
   296  	if self.vpcPC.AccepterVpcInfo != nil {
   297  		if self.vpcPC.AccepterVpcInfo.VpcId != nil {
   298  			return *self.vpcPC.AccepterVpcInfo.VpcId
   299  		}
   300  	}
   301  	return ""
   302  }
   303  
   304  func (self *SVpcPeeringConnection) GetPeerAccountId() string {
   305  	if self.vpcPC.AccepterVpcInfo != nil {
   306  		if self.vpcPC.AccepterVpcInfo.OwnerId != nil {
   307  			return *self.vpcPC.AccepterVpcInfo.OwnerId
   308  		}
   309  	}
   310  	return ""
   311  }
   312  
   313  func (self *SVpcPeeringConnection) Delete() error {
   314  	err := self.vpc.region.DeleteVpcPeeringConnection(self.GetId())
   315  	if err != nil {
   316  		return errors.Wrapf(err, "self.region.DeleteVpcPeeringConnection(%s)", self.GetId())
   317  	}
   318  	return nil
   319  }
   320  
   321  func (self *SVpcPeeringConnection) GetEnabled() bool {
   322  	return true
   323  }