Skip to content

Commit

Permalink
Binary for mtu and veth prefix check (#1458)
Browse files Browse the repository at this point in the history
* Added binary support to validate MTU value and Veth prefix

* Updated Dockerfile to include aws-node-config binary

* Added base64 deserialization logic
Improved logic to test veth pairs

* Removed Binary as it was redundant
Migrated MTU and Veth check to host networking binary instead
Updated env_vars_test file

* Separate MTU check from the default behavior

* Reverted Dockerfile changes

* Create deployment after changing MTU and Veth prefix

* Minor change to MTU validation logic

Co-authored-by: Chinmay Gadgil <[email protected]>
  • Loading branch information
cgchinmay and Chinmay Gadgil authored May 19, 2021
1 parent d428990 commit 4d1931b
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 136 deletions.
10 changes: 10 additions & 0 deletions test/agent/cmd/networking/tester/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ func TestNetworkingSetupForRegularPod(podNetworkingValidationInput input.PodNetw
continue
}

// Validate MTU value if it is set to true
if podNetworkingValidationInput.ValidateMTU {
if link.Attrs().MTU != podNetworkingValidationInput.MTU {
validationErrors = append(validationErrors,
fmt.Errorf("MTU value %v for pod: %s on veth pair: %s failed to match the expected value: %v", link.Attrs().MTU, pod.PodName, hostVethName, podNetworkingValidationInput.MTU))
} else {
log.Printf("Found Valid MTU value:%d for pod: %s on veth Pair: %s\n", link.Attrs().MTU, pod.PodName, hostVethName)
}
}

// Verify IP Link for the Pod is UP
isLinkUp := strings.Contains(link.Attrs().Flags.String(), "up")
if !isLinkUp {
Expand Down
14 changes: 14 additions & 0 deletions test/agent/pkg/input/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

package input

import "encoding/json"

type TestStatus struct {
SuccessCount int
FailureCount int
Expand All @@ -32,6 +34,10 @@ type PodNetworkingValidationInput struct {
VethPrefix string
// List of pod to validate the networking
PodList []Pod
// Should Validate MTU value, by default it will false
ValidateMTU bool
// Expected MTU value
MTU int
}

type Pod struct {
Expand All @@ -45,3 +51,11 @@ type Pod struct {
// from the Secondary ENI
IsIPFromSecondaryENI bool
}

func (ip PodNetworkingValidationInput) Serialize() (string, error) {
inputBytes, err := json.Marshal(ip)
if err != nil {
return "", err
}
return string(inputBytes), nil
}
11 changes: 11 additions & 0 deletions test/framework/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package utils

import (
appsV1 "k8s.io/api/apps/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
Expand All @@ -25,3 +26,13 @@ func NamespacedName(obj v1.Object) types.NamespacedName {
Name: obj.GetName(),
}
}

func GetEnvValueForKeyFromDaemonSet(key string, ds *appsV1.DaemonSet) string {
envVar := ds.Spec.Template.Spec.Containers[0].Env
for _, env := range envVar {
if env.Name == key {
return env.Value
}
}
return ""
}
95 changes: 82 additions & 13 deletions test/integration-new/cni/host_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
package cni

import (
"encoding/json"
"fmt"
"strconv"
"time"

"github.com/aws/amazon-vpc-cni-k8s/test/agent/pkg/input"
v1 "k8s.io/api/core/v1"

"github.com/aws/amazon-vpc-cni-k8s/test/framework/resources/k8s/manifest"
k8sUtils "github.com/aws/amazon-vpc-cni-k8s/test/framework/resources/k8s/utils"
"github.com/aws/amazon-vpc-cni-k8s/test/framework/utils"

. "github.com/onsi/ginkgo"
Expand All @@ -39,6 +40,13 @@ const (
NetworkingSetupFails
)

const (
AWS_VPC_ENI_MTU = "AWS_VPC_ENI_MTU"
AWS_VPC_K8S_CNI_VETHPREFIX = "AWS_VPC_K8S_CNI_VETHPREFIX"
NEW_MTU_VAL = 1300
NEW_VETH_PREFIX = "veth"
)

var _ = Describe("test host networking", func() {
var err error
var podLabelKey = "app"
Expand Down Expand Up @@ -71,7 +79,8 @@ var _ = Describe("test host networking", func() {
Should(BeNumerically(">", 0))

By("generating the pod networking validation input to be passed to tester")
input := GetPodNetworkingValidationInput(interfaceTypeToPodList)
input, err := GetPodNetworkingValidationInput(interfaceTypeToPodList).Serialize()
Expect(err).NotTo(HaveOccurred())

By("validating host networking setup is setup correctly")
ValidateHostNetworking(NetworkingSetupSucceeds, input)
Expand All @@ -87,6 +96,64 @@ var _ = Describe("test host networking", func() {
By("validating host networking is teared down correctly")
ValidateHostNetworking(NetworkingTearDownSucceeds, input)
})

It("Validate Host Networking setup after changing MTU and Veth Prefix", func() {
deployment := manifest.NewBusyBoxDeploymentBuilder().
Replicas(6).
PodLabel(podLabelKey, podLabelVal).
NodeName(primaryNode.Name).
Build()

By("Configuring Veth Prefix and MTU value on aws-node daemonset")
ds, err := f.K8sResourceManagers.DaemonSetManager().GetDaemonSet(utils.AwsNodeNamespace, utils.AwsNodeName)
Expect(err).NotTo(HaveOccurred())

oldMTU := utils.GetEnvValueForKeyFromDaemonSet(AWS_VPC_ENI_MTU, ds)
oldVethPrefix := utils.GetEnvValueForKeyFromDaemonSet(AWS_VPC_K8S_CNI_VETHPREFIX, ds)

k8sUtils.AddEnvVarToDaemonSetAndWaitTillUpdated(f, utils.AwsNodeName, utils.AwsNodeNamespace, utils.AwsNodeName, map[string]string{
AWS_VPC_ENI_MTU: strconv.Itoa(NEW_MTU_VAL),
AWS_VPC_K8S_CNI_VETHPREFIX: NEW_VETH_PREFIX,
})

By("creating a deployment to launch pods")
deployment, err = f.K8sResourceManagers.DeploymentManager().
CreateAndWaitTillDeploymentIsReady(deployment, utils.DefaultDeploymentReadyTimeout)
Expect(err).ToNot(HaveOccurred())

By("getting the list of pods using IP from primary and secondary ENI")
interfaceTypeToPodList :=
GetPodsOnPrimaryAndSecondaryInterface(primaryNode, podLabelKey, podLabelVal)

By("generating the pod networking validation input to be passed to tester")
podNetworkingValidationInput := GetPodNetworkingValidationInput(interfaceTypeToPodList)
podNetworkingValidationInput.VethPrefix = NEW_VETH_PREFIX
podNetworkingValidationInput.ValidateMTU = true
podNetworkingValidationInput.MTU = NEW_MTU_VAL
input, err := podNetworkingValidationInput.Serialize()
Expect(err).NotTo(HaveOccurred())

By("validating host networking setup is setup correctly with MTU check as well")
ValidateHostNetworking(NetworkingSetupSucceeds, input)

// Restore MTU and Veth Prefix
By("Restoring MTU value and Veth Prefix to old values")
k8sUtils.AddEnvVarToDaemonSetAndWaitTillUpdated(f, utils.AwsNodeName, utils.AwsNodeNamespace, utils.AwsNodeName, map[string]string{
AWS_VPC_ENI_MTU: oldMTU,
AWS_VPC_K8S_CNI_VETHPREFIX: oldVethPrefix,
})

By("deleting the deployment to test teardown")
err = f.K8sResourceManagers.DeploymentManager().
DeleteAndWaitTillDeploymentIsDeleted(deployment)
Expect(err).ToNot(HaveOccurred())

By("waiting to allow CNI to tear down networking for terminated pods")
time.Sleep(time.Second * 60)

By("validating host networking is teared down correctly")
ValidateHostNetworking(NetworkingTearDownSucceeds, input)
})
})

Context("when host networking is tested on invalid input", func() {
Expand All @@ -103,9 +170,10 @@ var _ = Describe("test host networking", func() {
CreatAndWaitTillRunning(parkingPod)
Expect(err).ToNot(HaveOccurred())

validInput := GetPodNetworkingValidationInput(InterfaceTypeToPodList{
validInput, err := GetPodNetworkingValidationInput(InterfaceTypeToPodList{
PodsOnPrimaryENI: []v1.Pod{*parkingPod},
})
}).Serialize()
Expect(err).NotTo(HaveOccurred())

By("first validating the tester work on valid input")
ValidateHostNetworking(NetworkingSetupSucceeds, validInput)
Expand All @@ -114,19 +182,22 @@ var _ = Describe("test host networking", func() {
invalidPod := parkingPod.DeepCopy()
invalidPod.Status.PodIP = "1.1.1.1"

invalidInput := GetPodNetworkingValidationInput(InterfaceTypeToPodList{
invalidInput, err := GetPodNetworkingValidationInput(InterfaceTypeToPodList{
PodsOnPrimaryENI: []v1.Pod{*invalidPod},
})
}).Serialize()
Expect(err).NotTo(HaveOccurred())

ValidateHostNetworking(NetworkingSetupFails, invalidInput)

By("validating the tester fails when invalid namespace is passed")
invalidPod = parkingPod.DeepCopy()
// veth pair name is generated using namespace+name so the test should fail
invalidPod.Namespace = "different"

invalidInput = GetPodNetworkingValidationInput(InterfaceTypeToPodList{
invalidInput, err = GetPodNetworkingValidationInput(InterfaceTypeToPodList{
PodsOnPrimaryENI: []v1.Pod{*invalidPod},
})
}).Serialize()
Expect(err).NotTo(HaveOccurred())

ValidateHostNetworking(NetworkingSetupFails, invalidInput)

Expand Down Expand Up @@ -194,12 +265,13 @@ func ValidateHostNetworking(testType TestType, podValidationInputString string)

// GetPodNetworkingValidationInput returns input string containing the list of pods for which
// the host networking has to be tested
func GetPodNetworkingValidationInput(interfaceTypeToPodList InterfaceTypeToPodList) string {
func GetPodNetworkingValidationInput(interfaceTypeToPodList InterfaceTypeToPodList) input.PodNetworkingValidationInput {

ip := input.PodNetworkingValidationInput{
VPCCidrRange: vpcCIDRs,
VethPrefix: "eni",
PodList: []input.Pod{},
ValidateMTU: false,
}

for _, primaryENIPod := range interfaceTypeToPodList.PodsOnPrimaryENI {
Expand All @@ -220,8 +292,5 @@ func GetPodNetworkingValidationInput(interfaceTypeToPodList InterfaceTypeToPodLi
})
}

inputBytes, err := json.Marshal(ip)
Expect(err).ToNot(HaveOccurred())

return string(inputBytes)
return ip
}
Loading

0 comments on commit 4d1931b

Please sign in to comment.