mirror of https://github.com/k3s-io/k3s
Enhanced detection of VPC for cloudprovider AWS
* use metadata of instance rather than hardcoded VPC name * test coverage for retrieval of network metadatapull/6/head
parent
64717962cf
commit
1bfba8a590
|
@ -1281,12 +1281,41 @@ func (self *AWSCloud) TCPLoadBalancerExists(name, region string) (bool, error) {
|
|||
return false, nil
|
||||
}
|
||||
|
||||
// Retrieves instance's vpc id from metadata
|
||||
func (self *AWSCloud) findVPCID() (string, error) {
|
||||
|
||||
metadata := self.awsServices.Metadata()
|
||||
macsBytes, err := metadata.GetMetaData("network/interfaces/macs/")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Could not list interfaces of the instance", err)
|
||||
}
|
||||
|
||||
// loop over interfaces, first vpc id returned wins
|
||||
for _, macPath := range strings.Split(string(macsBytes), "\n") {
|
||||
|
||||
if len(macPath) == 0 {
|
||||
continue
|
||||
}
|
||||
url := fmt.Sprintf("network/interfaces/macs/%svpc-id", macPath)
|
||||
vpcIDBytes, err := metadata.GetMetaData(url)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return string(vpcIDBytes), nil
|
||||
}
|
||||
return "", fmt.Errorf("Could not find VPC id in instance metadata")
|
||||
}
|
||||
|
||||
// Find the kubernetes VPC
|
||||
func (self *AWSCloud) findVPC() (*ec2.VPC, error) {
|
||||
request := &ec2.DescribeVPCsInput{}
|
||||
|
||||
name := "kubernetes-vpc"
|
||||
filters := []*ec2.Filter{newEc2Filter("tag:Name", name)}
|
||||
// find by vpcID from metadata
|
||||
vpcID, err := self.findVPCID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
filters := []*ec2.Filter{newEc2Filter("vpc-id", vpcID)}
|
||||
request.Filters = self.addFilters(filters)
|
||||
|
||||
vpcs, err := self.ec2.DescribeVPCs(request)
|
||||
|
@ -1301,7 +1330,7 @@ func (self *AWSCloud) findVPC() (*ec2.VPC, error) {
|
|||
if len(vpcs) == 1 {
|
||||
return vpcs[0], nil
|
||||
}
|
||||
return nil, fmt.Errorf("Found multiple matching VPCs for name: %s", name)
|
||||
return nil, fmt.Errorf("Found multiple matching VPCs for vpcID = %s", vpcID)
|
||||
}
|
||||
|
||||
// Retrieves the specified security group from the AWS API, or returns nil if not found
|
||||
|
|
|
@ -104,10 +104,12 @@ func TestReadAWSCloudConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
type FakeAWSServices struct {
|
||||
availabilityZone string
|
||||
instances []*ec2.Instance
|
||||
instanceId string
|
||||
privateDnsName string
|
||||
availabilityZone string
|
||||
instances []*ec2.Instance
|
||||
instanceId string
|
||||
privateDnsName string
|
||||
networkInterfacesMacs []string
|
||||
networkInterfacesVpcIDs []string
|
||||
|
||||
ec2 *FakeEC2
|
||||
elb *FakeELB
|
||||
|
@ -123,6 +125,9 @@ func NewFakeAWSServices() *FakeAWSServices {
|
|||
s.asg = &FakeASG{aws: s}
|
||||
s.metadata = &FakeMetadata{aws: s}
|
||||
|
||||
s.networkInterfacesMacs = []string{"aa:bb:cc:dd:ee:00", "aa:bb:cc:dd:ee:01"}
|
||||
s.networkInterfacesVpcIDs = []string{"vpc-mac0", "vpc-mac1"}
|
||||
|
||||
s.instanceId = "i-self"
|
||||
s.privateDnsName = "ip-172-20-0-100.ec2.internal"
|
||||
var selfInstance ec2.Instance
|
||||
|
@ -308,12 +313,28 @@ type FakeMetadata struct {
|
|||
}
|
||||
|
||||
func (self *FakeMetadata) GetMetaData(key string) ([]byte, error) {
|
||||
networkInterfacesPrefix := "network/interfaces/macs/"
|
||||
if key == "placement/availability-zone" {
|
||||
return []byte(self.aws.availabilityZone), nil
|
||||
} else if key == "instance-id" {
|
||||
return []byte(self.aws.instanceId), nil
|
||||
} else if key == "local-hostname" {
|
||||
return []byte(self.aws.privateDnsName), nil
|
||||
} else if strings.HasPrefix(key, networkInterfacesPrefix) {
|
||||
if key == networkInterfacesPrefix {
|
||||
return []byte(strings.Join(self.aws.networkInterfacesMacs, "/\n") + "/\n"), nil
|
||||
} else {
|
||||
keySplit := strings.Split(key, "/")
|
||||
macParam := keySplit[3]
|
||||
if len(keySplit) == 5 && keySplit[4] == "vpc-id" {
|
||||
for i, macElem := range self.aws.networkInterfacesMacs {
|
||||
if macParam == macElem {
|
||||
return []byte(self.aws.networkInterfacesVpcIDs[i]), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -627,3 +648,19 @@ func TestGetRegion(t *testing.T) {
|
|||
t.Errorf("Unexpected FailureDomain: %s", zone.FailureDomain)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindVPCID(t *testing.T) {
|
||||
awsServices := NewFakeAWSServices()
|
||||
c, err := newAWSCloud(strings.NewReader("[global]"), awsServices)
|
||||
if err != nil {
|
||||
t.Errorf("Error building aws cloud: %v", err)
|
||||
return
|
||||
}
|
||||
vpcID, err := c.findVPCID()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error:", err)
|
||||
}
|
||||
if vpcID != "vpc-mac0" {
|
||||
t.Errorf("Unexpected vpcID: %s", vpcID)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue