Skip to content

Commit

Permalink
Passing Host IPv4 address to container metadata file
Browse files Browse the repository at this point in the history
  • Loading branch information
linkar-ec2 committed Dec 13, 2018
1 parent 663b59c commit bba72e6
Show file tree
Hide file tree
Showing 29 changed files with 817 additions and 115 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ test-artifacts-linux: $(LINUX_ARTIFACTS_TARGETS)
test-artifacts: test-artifacts-windows test-artifacts-linux

# Run our 'test' registry needed for integ and functional tests
test-registry: netkitten volumes-test namespace-tests pause-container squid awscli image-cleanup-test-images fluentd agent-introspection-validator taskmetadata-validator v3-task-endpoint-validator
test-registry: netkitten volumes-test namespace-tests pause-container squid awscli image-cleanup-test-images fluentd agent-introspection-validator taskmetadata-validator v3-task-endpoint-validator container-metadata-file-validator
@./scripts/setup-test-registry

test-in-docker:
Expand Down Expand Up @@ -288,7 +288,7 @@ namespace-tests:

# TODO, replace this with a build on dockerhub or a mechanism for the
# functional tests themselves to build this
.PHONY: squid awscli fluentd gremlin agent-introspection-validator taskmetadata-validator v3-task-endpoint-validator image-cleanup-test-images ecr-execution-role-image container-health-check-image telemetry-test-image
.PHONY: squid awscli fluentd gremlin agent-introspection-validator taskmetadata-validator v3-task-endpoint-validator container-metadata-file-validator image-cleanup-test-images ecr-execution-role-image container-health-check-image telemetry-test-image
squid:
$(MAKE) -C misc/squid $(MFLAGS)

Expand Down Expand Up @@ -316,6 +316,9 @@ taskmetadata-validator:
v3-task-endpoint-validator:
$(MAKE) -C misc/v3-task-endpoint-validator $(MFLAGS)

container-metadata-file-validator:
$(MAKE) -C misc/container-metadata-file-validator $(MFLAGS)

ecr-execution-role-image:
$(MAKE) -C misc/ecr $(MFLAGS)

Expand Down Expand Up @@ -377,6 +380,7 @@ clean:
-$(MAKE) -C misc/agent-introspection-validator $(MFLAGS) clean
-$(MAKE) -C misc/taskmetadata-validator $(MFLAGS) clean
-$(MAKE) -C misc/v3-task-endpoint-validator $(MFLAGS) clean
-$(MAKE) -C misc/container-metadata-file-validator $(MFLAGS) clean
-$(MAKE) -C misc/container-health $(MFLAGS) clean
-$(MAKE) -C misc/telemetry $(MFLAGS) clean
-rm -f .get-deps-stamp
Expand Down
13 changes: 13 additions & 0 deletions agent/app/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ func (agent *ecsAgent) doStart(containerChangeEventStream *eventstream.EventStre
if agent.cfg.ContainerMetadataEnabled {
agent.metadataManager.SetContainerInstanceARN(agent.containerInstanceARN)
agent.metadataManager.SetAvailabilityZone(agent.availabilityZone)
agent.metadataManager.SetHostPublicIPv4Address(agent.getHostPublicIPv4AddressFromEC2Metadata())
}

// Begin listening to the docker daemon and saving changes
Expand Down Expand Up @@ -662,3 +663,15 @@ func mergeTags(localTags []*ecs.Tag, ec2Tags []*ecs.Tag) []*ecs.Tag {

return utils.MapToTags(tagsMap)
}

// getHostPublicIPv4AddressFromEC2Metadata will retrieve the PublicIPAddress (IPv4) of this
// instance through the EC2 API
func (agent *ecsAgent) getHostPublicIPv4AddressFromEC2Metadata() string {
// Get instance ID from ec2 metadata client.
hostPublicIPv4Address, err := agent.ec2MetadataClient.PublicIPv4Address()
if err != nil {
seelog.Errorf("Unable to retrieve Host Instance PublicIPv4 Address: %v", err)
return ""
}
return hostPublicIPv4Address
}
44 changes: 41 additions & 3 deletions agent/app/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ import (
)

const (
clusterName = "some-cluster"
containerInstanceARN = "container-instance1"
availabilityZone = "us-west-2b"
clusterName = "some-cluster"
containerInstanceARN = "container-instance1"
availabilityZone = "us-west-2b"
hostPublicIPv4Address = "127.0.0.1"
)

var apiVersions = []dockerclient.DockerVersion{
Expand Down Expand Up @@ -302,6 +303,9 @@ func TestDoStartRegisterAvailabilityZone(t *testing.T) {
dockerClient, _, _ := setup(t)
defer ctrl.Finish()

ec2MetadataClient := mock_ec2.NewMockEC2MetadataClient(ctrl)
ec2MetadataClient.EXPECT().PublicIPv4Address().Return(hostPublicIPv4Address, nil)

var discoverEndpointsInvoked sync.WaitGroup
discoverEndpointsInvoked.Add(2)
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)
Expand Down Expand Up @@ -335,6 +339,7 @@ func TestDoStartRegisterAvailabilityZone(t *testing.T) {
"arn:123", availabilityZone, nil),
containermetadata.EXPECT().SetContainerInstanceARN("arn:123"),
containermetadata.EXPECT().SetAvailabilityZone(availabilityZone),
containermetadata.EXPECT().SetHostPublicIPv4Address(hostPublicIPv4Address),
imageManager.EXPECT().SetSaver(gomock.Any()),
dockerClient.EXPECT().ContainerEvents(gomock.Any()),
state.EXPECT().AllImageStates().Return(nil),
Expand All @@ -355,6 +360,7 @@ func TestDoStartRegisterAvailabilityZone(t *testing.T) {
mobyPlugins: mockMobyPlugins,
metadataManager: containermetadata,
terminationHandler: func(saver statemanager.Saver, taskEngine engine.TaskEngine) {},
ec2MetadataClient: ec2MetadataClient,
}

go agent.doStart(eventstream.NewEventStream("events", ctx),
Expand Down Expand Up @@ -1109,6 +1115,38 @@ func TestGetContainerInstanceTagsFromEC2APIFailToDescribeECSTagsForInstance(t *t
assert.Nil(t, resTags)
}

func TestGetHostPublicIPv4AddressFromEC2Metadata(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

ec2MetadataClient := mock_ec2.NewMockEC2MetadataClient(ctrl)
ec2Client := mock_ec2.NewMockClient(ctrl)

agent := &ecsAgent{
ec2MetadataClient: ec2MetadataClient,
ec2Client: ec2Client,
}
ec2MetadataClient.EXPECT().PublicIPv4Address().Return(hostPublicIPv4Address, nil)

assert.Equal(t, hostPublicIPv4Address, agent.getHostPublicIPv4AddressFromEC2Metadata())
}

func TestGetHostPublicIPv4AddressFromEC2MetadataFailWithError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

ec2MetadataClient := mock_ec2.NewMockEC2MetadataClient(ctrl)
ec2Client := mock_ec2.NewMockClient(ctrl)

agent := &ecsAgent{
ec2MetadataClient: ec2MetadataClient,
ec2Client: ec2Client,
}
ec2MetadataClient.EXPECT().PublicIPv4Address().Return("", errors.New("Unable to get IP Address"))

assert.Empty(t, agent.getHostPublicIPv4AddressFromEC2Metadata())
}

func getTestConfig() config.Config {
cfg := config.DefaultConfig()
cfg.TaskCPUMemLimit = config.ExplicitlyDisabled
Expand Down
9 changes: 9 additions & 0 deletions agent/containermetadata/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const (
type Manager interface {
SetContainerInstanceARN(string)
SetAvailabilityZone(string)
SetHostPublicIPv4Address(string)
Create(*docker.Config, *docker.HostConfig, *apitask.Task, string) error
Update(context.Context, string, *apitask.Task, string) error
Clean(string) error
Expand All @@ -68,6 +69,8 @@ type metadataManager struct {
ioutilWrap ioutilwrapper.IOUtil
// availabilityZone is the availabiltyZone where task is in
availabilityZone string
// hostPublicIPv4Address is the public IPv4 address associated with the EC2 instance ID
hostPublicIPv4Address string
}

// NewManager creates a metadataManager for a given DockerTaskEngine settings.
Expand All @@ -94,6 +97,12 @@ func (manager *metadataManager) SetAvailabilityZone(availabilityZone string) {
manager.availabilityZone = availabilityZone
}

// SetHostPublicIPv4Address sets the metadataManager's hostPublicIPv4Address which is not available
// at its creation as this information is not present immediately at the agent's startup
func (manager *metadataManager) SetHostPublicIPv4Address(ipv4address string) {
manager.hostPublicIPv4Address = ipv4address
}

// Create creates the metadata file and adds the metadata directory to
// the container's mounted host volumes
// Pointer hostConfig is modified directly so there is risk of concurrency errors.
Expand Down
10 changes: 10 additions & 0 deletions agent/containermetadata/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const (
containerName = "container"
dataDir = "ecs_mockdata"
availabilityZone = "us-west-2b"
hostPublicIPv4Address = "127.0.0.1"
)

func managerSetup(t *testing.T) (*mock_containermetadata.MockDockerMetadataClient, *mock_ioutilwrapper.MockIOUtil, *mock_oswrapper.MockOS, *mock_oswrapper.MockFile, func()) {
Expand Down Expand Up @@ -73,6 +74,15 @@ func TestSetAvailabilityZone(t *testing.T) {
assert.Equal(t, mockAvailabilityZone, newManager.availabilityZone)
}

// TestSetHostPublicIPv4Address checks whether the container hostPublicIPv4Address is set correctly.
func TestSetHostPublicIPv4Address(t *testing.T) {
_, _, _, _, done := managerSetup(t)
defer done()
newManager := &metadataManager{}
newManager.SetHostPublicIPv4Address(hostPublicIPv4Address)
assert.Equal(t, hostPublicIPv4Address, newManager.hostPublicIPv4Address)
}

// TestCreateMalformedFilepath checks case when taskARN is invalid resulting in an invalid file path
func TestCreateMalformedFilepath(t *testing.T) {
_, _, _, _, done := managerSetup(t)
Expand Down
10 changes: 10 additions & 0 deletions agent/containermetadata/mocks/containermetadata_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions agent/containermetadata/parse_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ func (manager *metadataManager) parseMetadataAtContainerCreate(task *apitask.Tas
taskDefinitionFamily: task.Family,
taskDefinitionRevision: task.Version,
},
containerInstanceARN: manager.containerInstanceARN,
metadataStatus: MetadataInitial,
availabilityZone: manager.availabilityZone,
containerInstanceARN: manager.containerInstanceARN,
metadataStatus: MetadataInitial,
availabilityZone: manager.availabilityZone,
hostPublicIPv4Address: manager.hostPublicIPv4Address,
}
}

Expand All @@ -61,6 +62,7 @@ func (manager *metadataManager) parseMetadata(dockerContainer *docker.Container,
containerInstanceARN: manager.containerInstanceARN,
metadataStatus: MetadataReady,
availabilityZone: manager.availabilityZone,
hostPublicIPv4Address: manager.hostPublicIPv4Address,
}
}

Expand Down
Loading

0 comments on commit bba72e6

Please sign in to comment.