Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use CreateTags instead of TagResources #129

Merged
merged 1 commit into from
Jul 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 34 additions & 31 deletions pkg/awsutils/awsutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package awsutils

import (
"fmt"
"os"
"strconv"
"strings"
"time"
Expand All @@ -26,13 +27,10 @@ import (

"github.com/aws/amazon-vpc-cni-k8s/pkg/ec2metadata"
"github.com/aws/amazon-vpc-cni-k8s/pkg/ec2wrapper"
"github.com/aws/amazon-vpc-cni-k8s/pkg/resourcegroupstaggingapiwrapper"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
)

const (
Expand All @@ -53,8 +51,10 @@ const (
eniDescriptionPrefix = "aws-K8S-"
metadataOwnerID = "/owner-id"
// AllocENI need to choose a first free device number between 0 and maxENI
maxENIs = 128
eniTagKey = "k8s-eni-key"
maxENIs = 128
clusterNameEnvVar = "CLUSTER_NAME"
eniNodeTagKey = "node.k8s.amazonaws.com/instance_id"
eniClusterTagKey = "cluster.k8s.amazonaws.com/name"

retryDeleteENIInternal = 5 * time.Second

Expand Down Expand Up @@ -144,7 +144,6 @@ type EC2InstanceMetadataCache struct {

ec2Metadata ec2metadata.EC2Metadata
ec2SVC ec2wrapper.EC2
tagSVC resourcegroupstaggingapiwrapper.ResourceGroupsTaggingAPI
}

// ENIMetadata contains ENI information retrieved from EC2 meta data service
Expand Down Expand Up @@ -205,9 +204,6 @@ func New() (*EC2InstanceMetadataCache, error) {
ec2SVC := ec2wrapper.New(sess)
cache.ec2SVC = ec2SVC

tagSVC := resourcegroupstaggingapiwrapper.New(sess)
cache.tagSVC = tagSVC

err = cache.initWithEC2Metadata()
if err != nil {
return nil, err
Expand Down Expand Up @@ -625,37 +621,44 @@ func (cache *EC2InstanceMetadataCache) createENI() (string, error) {
}

func (cache *EC2InstanceMetadataCache) tagENI(eniID string) {
tagSvc := cache.tagSVC
arns := make([]*string, 0)

eniARN := &arn.ARN{
Partition: "aws",
Service: "ec2",
Region: cache.region,
AccountID: cache.accountID,
Resource: "network-interface/" + eniID}
arnString := eniARN.String()
arns = append(arns, aws.String(arnString))
// Tag the ENI with "node.k8s.amazonaws.com/instance_id=<instance_id>"
tags := []*ec2.Tag{
{
Key: aws.String(eniNodeTagKey),
Value: aws.String(cache.instanceID),
},
}

tags := make(map[string]*string)
// If the CLUSTER_NAME env var is present,
// tag the ENI with "cluster.k8s.amazonaws.com/name=<cluster_name>"
clusterName := os.Getenv(clusterNameEnvVar)
if clusterName != "" {
tags = append(tags, &ec2.Tag{
Key: aws.String(eniClusterTagKey),
Value: aws.String(clusterName),
})
}

tagValue := cache.instanceID
tags[eniTagKey] = aws.String(tagValue)
log.Debugf("Trying to tag newly created eni: keys=%s, value=%s", eniTagKey, tagValue)
for _, tag := range tags {
log.Debugf("Trying to tag newly created eni: key=%s, value=%s", aws.StringValue(tag.Key), aws.StringValue(tag.Value))
}

tagInput := &resourcegroupstaggingapi.TagResourcesInput{
ResourceARNList: arns,
Tags: tags,
input := &ec2.CreateTagsInput{
Resources: []*string{
aws.String(eniID),
},
Tags: tags,
}

start := time.Now()
_, err := tagSvc.TagResources(tagInput)
awsAPILatency.WithLabelValues("TagResources", fmt.Sprint(err != nil)).Observe(msSince(start))
_, err := cache.ec2SVC.CreateTags(input)
awsAPILatency.WithLabelValues("CreateTags", fmt.Sprint(err != nil)).Observe(msSince(start))
if err != nil {
awsAPIErrInc("TagResources", err)
log.Warnf("Fail to tag the newly created eni %s %v", eniID, err)
awsAPIErrInc("CreateTags", err)
log.Warnf("Failed to tag the newly created eni %s: %v", eniID, err)
} else {
log.Debugf("Tag the newly created eni with arn: %s", arnString)
log.Debugf("Successfully tagged ENI: %s", eniID)
}
}

Expand Down
67 changes: 32 additions & 35 deletions pkg/awsutils/awsutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (

"github.com/aws/amazon-vpc-cni-k8s/pkg/ec2metadata/mocks"
"github.com/aws/amazon-vpc-cni-k8s/pkg/ec2wrapper/mocks"
"github.com/aws/amazon-vpc-cni-k8s/pkg/resourcegroupstaggingapiwrapper/mocks"
)

const (
Expand All @@ -52,17 +51,15 @@ const (

func setup(t *testing.T) (*gomock.Controller,
*mock_ec2metadata.MockEC2Metadata,
*mock_ec2wrapper.MockEC2,
*mock_resourcegroupstaggingapiwrapper.MockResourceGroupsTaggingAPI) {
*mock_ec2wrapper.MockEC2) {
ctrl := gomock.NewController(t)
return ctrl,
mock_ec2metadata.NewMockEC2Metadata(ctrl),
mock_ec2wrapper.NewMockEC2(ctrl),
mock_resourcegroupstaggingapiwrapper.NewMockResourceGroupsTaggingAPI(ctrl)
mock_ec2wrapper.NewMockEC2(ctrl)
}

func TestInitWithEC2metadata(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand Down Expand Up @@ -93,7 +90,7 @@ func TestInitWithEC2metadata(t *testing.T) {
}

func TestInitWithEC2metadataVPCcidrErr(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand All @@ -117,7 +114,7 @@ func TestInitWithEC2metadataVPCcidrErr(t *testing.T) {
}

func TestInitWithEC2metadataSubnetErr(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand All @@ -139,7 +136,7 @@ func TestInitWithEC2metadataSubnetErr(t *testing.T) {
}

func TestInitWithEC2metadataSGErr(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand All @@ -160,7 +157,7 @@ func TestInitWithEC2metadataSGErr(t *testing.T) {
}

func TestInitWithEC2metadataENIErrs(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand All @@ -178,7 +175,7 @@ func TestInitWithEC2metadataENIErrs(t *testing.T) {
}

func TestInitWithEC2metadataMACErr(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand All @@ -195,7 +192,7 @@ func TestInitWithEC2metadataMACErr(t *testing.T) {
}

func TestInitWithEC2metadataLocalIPErr(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand All @@ -209,7 +206,7 @@ func TestInitWithEC2metadataLocalIPErr(t *testing.T) {
}

func TestInitWithEC2metadataInstanceErr(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, nil)
Expand All @@ -224,7 +221,7 @@ func TestInitWithEC2metadataInstanceErr(t *testing.T) {
}

func TestInitWithEC2metadataAZErr(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataAZ).Return(az, errors.New("Error on metadata AZ"))
Expand All @@ -236,7 +233,7 @@ func TestInitWithEC2metadataAZErr(t *testing.T) {
}

func TestSetPrimaryENs(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataMACPath).Return(primaryMAC+" "+eni2MAC, nil)
Expand All @@ -255,7 +252,7 @@ func TestSetPrimaryENs(t *testing.T) {
}

func TestGetAttachedENIs(t *testing.T) {
ctrl, mockMetadata, _, _ := setup(t)
ctrl, mockMetadata, _ := setup(t)
defer ctrl.Finish()

mockMetadata.EXPECT().GetMetadata(metadataMACPath).Return(primaryMAC+" "+eni2MAC, nil)
Expand All @@ -278,7 +275,7 @@ func TestGetAttachedENIs(t *testing.T) {
}

func TestAWSGetFreeDeviceNumberOnErr(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

// test error handling
Expand All @@ -291,7 +288,7 @@ func TestAWSGetFreeDeviceNumberOnErr(t *testing.T) {
}

func TestAWSGetFreeDeviceNumberNoDevice(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

// test no free index
Expand All @@ -318,13 +315,13 @@ func TestAWSGetFreeDeviceNumberNoDevice(t *testing.T) {
}

func TestAllocENI(t *testing.T) {
ctrl, _, mockEC2, mockTag := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

cureniID := eniID
eni := ec2.CreateNetworkInterfaceOutput{NetworkInterface: &ec2.NetworkInterface{NetworkInterfaceId: &cureniID}}
mockEC2.EXPECT().CreateNetworkInterface(gomock.Any()).Return(&eni, nil)
mockTag.EXPECT().TagResources(gomock.Any()).Return(nil, nil)
mockEC2.EXPECT().CreateTags(gomock.Any()).Return(nil, nil)

// 2 ENIs, uses device number 0 3, expect to find free at 1
ec2ENIs := make([]*ec2.InstanceNetworkInterface, 0)
Expand All @@ -351,19 +348,19 @@ func TestAllocENI(t *testing.T) {

mockEC2.EXPECT().ModifyNetworkInterfaceAttribute(gomock.Any()).Return(nil, nil)

ins := &EC2InstanceMetadataCache{ec2SVC: mockEC2, tagSVC: mockTag}
ins := &EC2InstanceMetadataCache{ec2SVC: mockEC2}
_, err := ins.AllocENI()
assert.NoError(t, err)
}

func TestAllocENINoFreeDevice(t *testing.T) {
ctrl, _, mockEC2, mockTag := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

cureniID := eniID
eni := ec2.CreateNetworkInterfaceOutput{NetworkInterface: &ec2.NetworkInterface{NetworkInterfaceId: &cureniID}}
mockEC2.EXPECT().CreateNetworkInterface(gomock.Any()).Return(&eni, nil)
mockTag.EXPECT().TagResources(gomock.Any()).Return(nil, nil)
mockEC2.EXPECT().CreateTags(gomock.Any()).Return(nil, nil)

// test no free index
ec2ENIs := make([]*ec2.InstanceNetworkInterface, 0)
Expand All @@ -383,20 +380,20 @@ func TestAllocENINoFreeDevice(t *testing.T) {

mockEC2.EXPECT().DeleteNetworkInterface(gomock.Any()).Return(nil, nil)

ins := &EC2InstanceMetadataCache{ec2SVC: mockEC2, tagSVC: mockTag}
ins := &EC2InstanceMetadataCache{ec2SVC: mockEC2}
_, err := ins.AllocENI()
assert.Error(t, err)

}

func TestAllocENIMaxReached(t *testing.T) {
ctrl, _, mockEC2, mockTag := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

cureniID := eniID
eni := ec2.CreateNetworkInterfaceOutput{NetworkInterface: &ec2.NetworkInterface{NetworkInterfaceId: &cureniID}}
mockEC2.EXPECT().CreateNetworkInterface(gomock.Any()).Return(&eni, nil)
mockTag.EXPECT().TagResources(gomock.Any()).Return(nil, nil)
mockEC2.EXPECT().CreateTags(gomock.Any()).Return(nil, nil)

// 2 ENIs, uses device number 0 3, expect to find free at 1
ec2ENIs := make([]*ec2.InstanceNetworkInterface, 0)
Expand All @@ -419,13 +416,13 @@ func TestAllocENIMaxReached(t *testing.T) {
mockEC2.EXPECT().AttachNetworkInterface(gomock.Any()).Return(nil, errors.New("AttachmentLimitExceeded"))
mockEC2.EXPECT().DeleteNetworkInterface(gomock.Any()).Return(nil, nil)

ins := &EC2InstanceMetadataCache{ec2SVC: mockEC2, tagSVC: mockTag}
ins := &EC2InstanceMetadataCache{ec2SVC: mockEC2}
_, err := ins.AllocENI()
assert.Error(t, err)
}

func TestFreeENI(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

attachmentID := eniAttachID
Expand All @@ -442,7 +439,7 @@ func TestFreeENI(t *testing.T) {
}

func TestFreeENIRetry(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

attachmentID := eniAttachID
Expand All @@ -462,7 +459,7 @@ func TestFreeENIRetry(t *testing.T) {
}

func TestFreeENIRetryMax(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

attachmentID := eniAttachID
Expand All @@ -484,7 +481,7 @@ func TestFreeENIRetryMax(t *testing.T) {
}

func TestFreeENIDescribeErr(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

mockEC2.EXPECT().DescribeNetworkInterfaces(gomock.Any()).Return(nil, errors.New("Error on DescribeNetworkInterfaces"))
Expand All @@ -495,7 +492,7 @@ func TestFreeENIDescribeErr(t *testing.T) {
}

func TestAllocIPAddress(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

testIP := ec2.AssignPrivateIpAddressesOutput{}
Expand All @@ -509,7 +506,7 @@ func TestAllocIPAddress(t *testing.T) {
}

func TestAllocIPAddressOnErr(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

mockEC2.EXPECT().AssignPrivateIpAddresses(gomock.Any()).Return(nil, errors.New("Error on AssignPrivateIpAddresses"))
Expand All @@ -522,7 +519,7 @@ func TestAllocIPAddressOnErr(t *testing.T) {
}

func TestAllocAllIPAddress(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

// the expected addresses for t2.nano
Expand Down Expand Up @@ -553,7 +550,7 @@ func TestAllocAllIPAddress(t *testing.T) {
}

func TestAllocAllIPAddressOnErr(t *testing.T) {
ctrl, _, mockEC2, _ := setup(t)
ctrl, _, mockEC2 := setup(t)
defer ctrl.Finish()

// 2 addresses
Expand Down
Loading