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(¶ms) 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(¶ms) 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(¶ms) 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(¶ms) 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(¶ms) 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(¶ms) 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 }