yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aws/instancenic.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 "strings" 19 20 "github.com/aws/aws-sdk-go/aws" 21 "github.com/aws/aws-sdk-go/aws/awserr" 22 "github.com/aws/aws-sdk-go/service/ec2" 23 24 "yunion.io/x/pkg/errors" 25 26 "yunion.io/x/cloudmux/pkg/cloudprovider" 27 ) 28 29 type SInstanceNic struct { 30 instance *SInstance 31 32 id string 33 ipAddr string 34 macAddr string 35 36 cloudprovider.DummyICloudNic 37 } 38 39 func (self *SInstanceNic) GetId() string { 40 return self.id 41 } 42 43 func (self *SInstanceNic) GetIP() string { 44 return self.ipAddr 45 } 46 47 func (self *SInstanceNic) GetMAC() string { 48 return self.macAddr 49 } 50 51 func (self *SInstanceNic) InClassicNetwork() bool { 52 return false 53 } 54 55 func (self *SInstanceNic) GetDriver() string { 56 return "virtio" 57 } 58 59 func (self *SInstanceNic) GetINetworkId() string { 60 return self.instance.VpcAttributes.NetworkId 61 } 62 63 func (self *SInstanceNic) getEc2Client() *ec2.EC2 { 64 ec2Client, err := self.instance.host.zone.region.getEc2Client() 65 if err != nil { 66 return nil 67 } 68 return ec2Client 69 } 70 71 func (self *SInstanceNic) GetSubAddress() ([]string, error) { 72 var ( 73 ec2Client = self.getEc2Client() 74 id = self.GetId() 75 input = &ec2.DescribeNetworkInterfacesInput{ 76 NetworkInterfaceIds: []*string{ 77 aws.String(id), 78 }, 79 } 80 ) 81 output, err := ec2Client.DescribeNetworkInterfaces(input) 82 if err != nil { 83 return nil, errors.Wrapf(err, "aws ec2 DescribeNetworkInterfaces") 84 } 85 if got := len(output.NetworkInterfaces); got != 1 { 86 return nil, errors.Errorf("got aws %d network interface, want 1", got) 87 } 88 networkInterface := output.NetworkInterfaces[0] 89 if got := aws.StringValue(networkInterface.NetworkInterfaceId); got != id { 90 return nil, errors.Errorf("got aws network interface %s, want %s", got, id) 91 } 92 var ipAddrs []string 93 for _, privateIp := range networkInterface.PrivateIpAddresses { 94 if !aws.BoolValue(privateIp.Primary) { 95 ipAddrs = append(ipAddrs, *privateIp.PrivateIpAddress) 96 } 97 } 98 return ipAddrs, nil 99 } 100 101 func (self *SInstanceNic) AssignAddress(ipAddrs []string) error { 102 var ( 103 ec2Client = self.getEc2Client() 104 id = self.GetId() 105 input = &ec2.AssignPrivateIpAddressesInput{ 106 NetworkInterfaceId: aws.String(id), 107 PrivateIpAddresses: aws.StringSlice(ipAddrs), 108 } 109 ) 110 _, err := ec2Client.AssignPrivateIpAddresses(input) 111 if err != nil { 112 if aerr, ok := err.(awserr.Error); ok { 113 switch aerr.Code() { 114 case "PrivateIpAddressLimitExceeded": 115 return errors.Wrapf(cloudprovider.ErrAddressCountExceed, "aws ec2 AssignPrivateIpAddresses: %v", err) 116 } 117 } 118 return errors.Wrapf(err, "aws ec2 AssignPrivateIpAddresses") 119 } 120 return nil 121 } 122 123 func (self *SInstanceNic) UnassignAddress(ipAddrs []string) error { 124 var ( 125 ec2Client = self.getEc2Client() 126 id = self.GetId() 127 input = &ec2.UnassignPrivateIpAddressesInput{ 128 NetworkInterfaceId: aws.String(id), 129 PrivateIpAddresses: aws.StringSlice(ipAddrs), 130 } 131 ) 132 _, err := ec2Client.UnassignPrivateIpAddresses(input) 133 if err != nil { 134 if aerr, ok := err.(awserr.Error); ok { 135 switch aerr.Code() { 136 case "InvalidNetworkInterfaceID.NotFound": 137 return nil 138 case "InvalidParameterValue": 139 msg := aerr.Message() 140 // "Some of the specified addresses are not assigned to interface eni-xxxxxxxxxxxxxxxxx" 141 if strings.Contains(msg, " addresses are not assigned to interface ") { 142 return nil 143 } 144 } 145 } 146 return errors.Wrapf(err, "aws ec2 UnassignPrivateIpAddresses") 147 } 148 return nil 149 }