github.com/imran-kn/cilium-fork@v1.6.9/pkg/policy/groups/aws/aws.go (about) 1 // Copyright 2018 Authors of Cilium 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 package aws 15 16 import ( 17 "fmt" 18 "net" 19 "os" 20 21 "github.com/aws/aws-sdk-go-v2/aws" 22 "github.com/aws/aws-sdk-go-v2/aws/external" 23 "github.com/aws/aws-sdk-go-v2/service/ec2" 24 "github.com/cilium/cilium/pkg/policy/api" 25 ) 26 27 const ( 28 awsLogLevel = aws.LogOff // For debugging pourposes can be set to aws.LogDebugWithSigning 29 awsDefaultRegionKey = "AWS_DEFAULT_REGION" 30 awsDefaultRegion = "eu-west-1" 31 ) 32 33 var ( 34 policySecurityGroupIDKey = aws.String("instance.group-id") 35 policySecurityGroupName = aws.String("instance.group-name") 36 policyEC2Labelskey = "tag" 37 ) 38 39 func init() { 40 api.RegisterToGroupsProvider(api.AWSProvider, GetIPsFromGroup) 41 } 42 43 // GetIPsFromGroup will return the list of the ips for the given group filter 44 func GetIPsFromGroup(group *api.ToGroups) ([]net.IP, error) { 45 result := []net.IP{} 46 if group.AWS == nil { 47 return result, fmt.Errorf("no aws data available") 48 } 49 return getInstancesIpsFromFilter(group.AWS) 50 } 51 52 // initializeAWSAccount retrieve the env variables from the runtime and it 53 // iniliazes the account in the specified region. 54 func initializeAWSAccount(region string) (*aws.Config, error) { 55 cfg, err := external.LoadDefaultAWSConfig() 56 if err != nil { 57 return nil, fmt.Errorf("Cannot initialize aws connector: %s", err) 58 } 59 cfg.Region = region 60 cfg.LogLevel = awsLogLevel 61 return &cfg, nil 62 } 63 64 // getInstancesFromFilter returns the instances IPs in aws EC2 filter by the 65 // given filter 66 func getInstancesIpsFromFilter(filter *api.AWSGroup) ([]net.IP, error) { 67 region := filter.Region 68 if filter.Region == "" { 69 region = getDefaultRegion() 70 } 71 input := &ec2.DescribeInstancesInput{} 72 for labelKey, labelValue := range filter.Labels { 73 newFilter := ec2.Filter{ 74 Name: aws.String(fmt.Sprintf("%s:%s", policyEC2Labelskey, labelKey)), 75 Values: []string{labelValue}, 76 } 77 input.Filters = append(input.Filters, newFilter) 78 } 79 if len(filter.SecurityGroupsIds) > 0 { 80 newFilter := ec2.Filter{ 81 Name: policySecurityGroupIDKey, 82 Values: filter.SecurityGroupsIds, 83 } 84 input.Filters = append(input.Filters, newFilter) 85 } 86 if len(filter.SecurityGroupsNames) > 0 { 87 newFilter := ec2.Filter{ 88 Name: policySecurityGroupName, 89 Values: filter.SecurityGroupsNames, 90 } 91 input.Filters = append(input.Filters, newFilter) 92 } 93 cfg, err := initializeAWSAccount(region) 94 if err != nil { 95 return []net.IP{}, err 96 } 97 svc := ec2.New(*cfg) 98 req := svc.DescribeInstancesRequest(input) 99 result, err := req.Send() 100 if err != nil { 101 return []net.IP{}, fmt.Errorf("Cannot retrieve aws information: %s", err) 102 } 103 return awsDumpIpsFromRequest(result), nil 104 } 105 106 // getDefaultRegion returns the given region of the default one. 107 // @TODO retrieve the region from aws metadata. 108 func getDefaultRegion() string { 109 val := os.Getenv(awsDefaultRegionKey) 110 if val != "" { 111 return val 112 } 113 return awsDefaultRegion 114 } 115 116 func awsDumpIpsFromRequest(req *ec2.DescribeInstancesOutput) []net.IP { 117 result := []net.IP{} 118 for _, reservation := range req.Reservations { 119 for _, instance := range reservation.Instances { 120 for _, iface := range instance.NetworkInterfaces { 121 for _, ifaceIP := range iface.PrivateIpAddresses { 122 result = append(result, net.ParseIP(string(*ifaceIP.PrivateIpAddress))) 123 if ifaceIP.Association != nil { 124 result = append(result, net.ParseIP(string(*ifaceIP.Association.PublicIp))) 125 } 126 } 127 } 128 } 129 } 130 return result 131 }