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

Add new network data structures #3909

Merged
merged 10 commits into from
Sep 21, 2023
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
42 changes: 42 additions & 0 deletions ecs-agent/netlib/model/status/network_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package status

// NetworkStatus represents the status of a network resource.
type NetworkStatus string

const (
// NetworkNone is the initial status of the ENI.
NetworkNone NetworkStatus = "NONE"
// NetworkReadyPull indicates that the ENI is ready for downloading resources associated with
// the execution role. This includes container images, task secrets and configs.
NetworkReadyPull NetworkStatus = "READY_PULL"
// NetworkReady indicates that the ENI is ready for use by containers in the task.
NetworkReady NetworkStatus = "READY"
// NetworkDeleted indicates that the ENI is deleted.
NetworkDeleted NetworkStatus = "DELETED"
)

var (
eniStatusOrder = map[NetworkStatus]int{
Realmonia marked this conversation as resolved.
Show resolved Hide resolved
NetworkNone: 0,
NetworkReadyPull: 1,
NetworkReady: 2,
NetworkDeleted: 3,
}
)

func (es NetworkStatus) String() string {
return string(es)
}

func (es NetworkStatus) ENIStatusBackwards(es2 NetworkStatus) bool {
return eniStatusOrder[es] < eniStatusOrder[es2]
}

func GetAllENIStatuses() []NetworkStatus {
return []NetworkStatus{
NetworkNone,
NetworkReadyPull,
NetworkReady,
NetworkDeleted,
}
}
52 changes: 52 additions & 0 deletions ecs-agent/netlib/model/status/network_status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//go:build unit
// +build unit

package status

import (
"testing"

"github.com/stretchr/testify/assert"
)

// TestNetworkStatus verifies the corresponding string values of each status
// is appropriate.
func TestNetworkStatus(t *testing.T) {
testCases := []struct {
status NetworkStatus
str string
}{
{
status: NetworkNone,
str: "NONE",
},
{
status: NetworkReadyPull,
str: "READY_PULL",
},
{
status: NetworkReady,
str: "READY",
},
{
status: NetworkDeleted,
str: "DELETED",
},
}
for _, tc := range testCases {
t.Run(tc.str, func(t *testing.T) {
assert.Equal(t, tc.str, (&tc.status).String())
})
}
}

// TestNetworkStatusOrder verifies that order of statuses are as required.
func TestNetworkStatusOrder(t *testing.T) {
assert.True(t, NetworkNone.ENIStatusBackwards(NetworkReadyPull))
assert.True(t, NetworkReadyPull.ENIStatusBackwards(NetworkReady))
assert.True(t, NetworkReady.ENIStatusBackwards(NetworkDeleted))

assert.False(t, NetworkReadyPull.ENIStatusBackwards(NetworkNone))
assert.False(t, NetworkReady.ENIStatusBackwards(NetworkReadyPull))
assert.False(t, NetworkDeleted.ENIStatusBackwards(NetworkReady))
}
44 changes: 44 additions & 0 deletions ecs-agent/netlib/model/tasknetworkconfig/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package tasknetworkconfig

import ni "github.com/aws/amazon-ecs-agent/ecs-agent/netlib/model/networkinterface"

const (
primaryNetNSName = "primary-netns"
secondaryNetNSName = "secondary-netns"
primaryInterfaceName = "primary-interface"
secondaryInterfaceName = "secondary-interface"
)

func getTestTaskNetworkConfig() *TaskNetworkConfig {
return &TaskNetworkConfig{
NetworkNamespaces: getTestNetworkNamespaces(),
}
}

func getTestNetworkNamespaces() []*NetworkNamespace {
return []*NetworkNamespace{
{
Name: secondaryNetNSName,
Index: 1,
NetworkInterfaces: getTestNetworkInterfaces(),
},
{
Name: primaryNetNSName,
Index: 0,
NetworkInterfaces: getTestNetworkInterfaces(),
},
}
}

func getTestNetworkInterfaces() []*ni.NetworkInterface {
return []*ni.NetworkInterface{
{
Name: secondaryInterfaceName,
Index: 1,
},
{
Name: primaryInterfaceName,
Index: 0,
},
}
}
35 changes: 35 additions & 0 deletions ecs-agent/netlib/model/tasknetworkconfig/network_namespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package tasknetworkconfig

import (
"github.com/aws/amazon-ecs-agent/ecs-agent/netlib/model/appmesh"
"github.com/aws/amazon-ecs-agent/ecs-agent/netlib/model/networkinterface"
)

// NetworkNamespace is model representing each network namespace.
type NetworkNamespace struct {
Name string
Path string
Index int

// NetworkInterfaces represents ENIs or any kind of network interface associated the particular netns.
NetworkInterfaces []*networkinterface.NetworkInterface

// AppMeshConfig holds AppMesh related parameters for the particular netns.
AppMeshConfig *appmesh.AppMesh

// TODO: Add Service Connect model here once it is moved under the netlib package.

KnownState string
DesiredState string
}

// GetPrimaryInterface returns the network interface that has the index value of 0 within
// the network namespace.
func (ns NetworkNamespace) GetPrimaryInterface() *networkinterface.NetworkInterface {
for _, ni := range ns.NetworkInterfaces {
if ni.Index == 0 {
return ni
}
}
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build unit
// +build unit

package tasknetworkconfig

import (
"github.com/aws/amazon-ecs-agent/ecs-agent/netlib/model/networkinterface"

"testing"

"github.com/stretchr/testify/assert"
)

func TestNetworkNamespace_GetPrimaryInterface(t *testing.T) {
netns := &NetworkNamespace{
NetworkInterfaces: []*networkinterface.NetworkInterface{
{
Index: 1,
Name: secondaryInterfaceName,
},
{
Index: 0,
Name: primaryInterfaceName,
},
},
}
assert.Equal(t, primaryInterfaceName, netns.GetPrimaryInterface().Name)

netns = &NetworkNamespace{}
assert.Empty(t, netns.GetPrimaryInterface())
}
29 changes: 29 additions & 0 deletions ecs-agent/netlib/model/tasknetworkconfig/task_network_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tasknetworkconfig

import ni "github.com/aws/amazon-ecs-agent/ecs-agent/netlib/model/networkinterface"

// TaskNetworkConfig is the top level network data structure associated with a task.
type TaskNetworkConfig struct {
NetworkNamespaces []*NetworkNamespace
NetworkMode string
}

// GetPrimaryInterface returns the interface with index 0 inside the network namespace
// with index 0 associated with the task's network config.
func (tnc *TaskNetworkConfig) GetPrimaryInterface() *ni.NetworkInterface {
if tnc != nil && tnc.GetPrimaryNetNS() != nil {
return tnc.GetPrimaryNetNS().GetPrimaryInterface()
}
return nil
}

// GetPrimaryNetNS returns the netns with index 0 associated with the task's network config.
func (tnc *TaskNetworkConfig) GetPrimaryNetNS() *NetworkNamespace {
for _, netns := range tnc.NetworkNamespaces {
if netns.Index == 0 {
return netns
}
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//go:build unit
// +build unit

package tasknetworkconfig

import (
"github.com/stretchr/testify/assert"

"testing"
)

func TestTaskNetworkConfig_GetPrimaryInterface(t *testing.T) {
testNetConfig := getTestTaskNetworkConfig()
assert.Equal(t, primaryInterfaceName, testNetConfig.GetPrimaryInterface().Name)

testNetConfig = &TaskNetworkConfig{
NetworkNamespaces: []*NetworkNamespace{},
}
assert.Nil(t, testNetConfig.GetPrimaryInterface())
}

func TestTaskNetworkConfig_GetPrimaryNetNS(t *testing.T) {
testNetConfig := getTestTaskNetworkConfig()
assert.Equal(t, primaryNetNSName, testNetConfig.GetPrimaryNetNS().Name)

testNetConfig = &TaskNetworkConfig{}
assert.Nil(t, testNetConfig.GetPrimaryNetNS())
}