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

Added Test cases for EnvVars check on CNI daemonset #1431

Merged
merged 13 commits into from
May 6, 2021
5 changes: 3 additions & 2 deletions test/framework/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Options struct {
AWSVPCID string
NgNameLabelKey string
NgNameLabelVal string
IgnoreOptional bool
cgchinmay marked this conversation as resolved.
Show resolved Hide resolved
}

func (options *Options) BindFlags() {
Expand All @@ -57,10 +58,10 @@ func (options *Options) Validate() error {
if len(options.AWSVPCID) == 0 {
return errors.Errorf("%s must be set!", "aws-vpc-id")
}
if len(options.NgNameLabelKey) == 0 {
if !options.IgnoreOptional && len(options.NgNameLabelKey) == 0 {
return errors.Errorf("%s must be set!", "ng-name-label-key")
}
if len(options.NgNameLabelVal) == 0 {
if !options.IgnoreOptional && len(options.NgNameLabelVal) == 0 {
return errors.Errorf("%s must be set!", "ng-name-label-val")
}

Expand Down
7 changes: 7 additions & 0 deletions test/framework/resources/k8s/manifest/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type DeploymentBuilder struct {
labels map[string]string
terminationGracePeriod int
nodeName string
hostNetwork bool
}

func NewBusyBoxDeploymentBuilder() *DeploymentBuilder {
Expand Down Expand Up @@ -86,6 +87,11 @@ func (d *DeploymentBuilder) PodLabel(labelKey string, labelValue string) *Deploy
return d
}

func (d *DeploymentBuilder) HostNetwork(hostNetwork bool) *DeploymentBuilder {
d.hostNetwork = hostNetwork
return d
}

func (d *DeploymentBuilder) Build() *v1.Deployment {
return &v1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -103,6 +109,7 @@ func (d *DeploymentBuilder) Build() *v1.Deployment {
Labels: d.labels,
},
Spec: corev1.PodSpec{
HostNetwork: d.hostNetwork,
Containers: []corev1.Container{d.container},
TerminationGracePeriodSeconds: aws.Int64(int64(d.terminationGracePeriod)),
NodeName: d.nodeName,
Expand Down
22 changes: 22 additions & 0 deletions test/framework/resources/k8s/resources/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/aws/amazon-vpc-cni-k8s/test/framework/utils"

v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -28,6 +29,7 @@ import (
type DeploymentManager interface {
CreateAndWaitTillDeploymentIsReady(deployment *v1.Deployment) (*v1.Deployment, error)
DeleteAndWaitTillDeploymentIsDeleted(deployment *v1.Deployment) error
MountVolume(deployment *v1.Deployment, name string, mountpath string)
cgchinmay marked this conversation as resolved.
Show resolved Hide resolved
}

type defaultDeploymentManager struct {
Expand Down Expand Up @@ -77,6 +79,26 @@ func (d defaultDeploymentManager) DeleteAndWaitTillDeploymentIsDeleted(deploymen
}, ctx.Done())
}

func (d defaultDeploymentManager) MountVolume(deployment *v1.Deployment, name string, mountpath string) {
deployment.Spec.Template.Spec.Volumes = []corev1.Volume{
{
Name: name,
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: mountpath,
},
},
},
}

deployment.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{
{
Name: name,
MountPath: name,
},
}
}

func NewDefaultDeploymentManager(k8sClient client.DelegatingClient) DeploymentManager {
return &defaultDeploymentManager{k8sClient: k8sClient}
}
8 changes: 8 additions & 0 deletions test/framework/resources/k8s/resources/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

type NodeManager interface {
GetNodes(nodeLabelKey string, nodeLabelVal string) (v1.NodeList, error)
GetAllNodes() (v1.NodeList, error)
}

type defaultNodeManager struct {
Expand All @@ -40,3 +41,10 @@ func (d *defaultNodeManager) GetNodes(nodeLabelKey string, nodeLabelVal string)
})
return nodeList, err
}

func (d *defaultNodeManager) GetAllNodes() (v1.NodeList, error) {
ctx := context.Background()
nodeList := v1.NodeList{}
err := d.k8sClient.List(ctx, &nodeList)
return nodeList, err
}
76 changes: 76 additions & 0 deletions test/integration-new/cni/env_vars/env_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package env_vars

import (
"testing"

"github.com/aws/amazon-vpc-cni-k8s/test/framework"
"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/onsi/ginkgo"
. "github.com/onsi/gomega"
appsV1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
)

const (
NAMESPACE = "kube-system"
DAEMONSET = "aws-node"
HOST_POD_LABEL_KEY = "network"
HOST_POD_LABEL_VAL = "host"
)

var (
primaryNode v1.Node
primaryInstanceId string
ds *appsV1.DaemonSet
f *framework.Framework
hostNetworkDeploymentSpec *appsV1.Deployment
hostNetworkDeployment *appsV1.Deployment
err error
hostNetworkPod v1.Pod
)

func TestCni(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Cni Suite")
}

var _ = BeforeSuite(func() {
globalOptions := framework.GlobalOptions
globalOptions.IgnoreOptional = true
f = framework.New(globalOptions)
ds, err = f.K8sResourceManagers.DaemonSetManager().GetDaemonSet(NAMESPACE, DAEMONSET)
Expect(err).NotTo(HaveOccurred())

nodes, err := f.K8sResourceManagers.NodeManager().GetAllNodes()
Expect(err).NotTo(HaveOccurred())
Expect(len(nodes.Items)).To(BeNumerically(">", 0))

primaryNode = nodes.Items[0]
primaryInstanceId = k8sUtils.GetInstanceIDFromNode(primaryNode)

hostNetworkDeploymentSpec = manifest.NewBusyBoxDeploymentBuilder().
Namespace("default").
Name("host-network").
Replicas(1).
HostNetwork(true).
PodLabel(HOST_POD_LABEL_KEY, HOST_POD_LABEL_VAL).
NodeName(primaryNode.Name).
Build()

f.K8sResourceManagers.DeploymentManager().MountVolume(hostNetworkDeploymentSpec, "ipamd-logs", "/var/log/aws-routed-eni/")
cgchinmay marked this conversation as resolved.
Show resolved Hide resolved
hostNetworkDeployment, err = f.K8sResourceManagers.
DeploymentManager().
CreateAndWaitTillDeploymentIsReady(hostNetworkDeploymentSpec)
Expect(err).NotTo(HaveOccurred())

pods, err := f.K8sResourceManagers.PodManager().GetPodsWithLabelSelector(HOST_POD_LABEL_KEY, HOST_POD_LABEL_VAL)
Expect(err).NotTo(HaveOccurred())

hostNetworkPod = pods.Items[0]
})

var _ = AfterSuite(func() {
err = f.K8sResourceManagers.DeploymentManager().DeleteAndWaitTillDeploymentIsDeleted(hostNetworkDeploymentSpec)
Expect(err).NotTo(HaveOccurred())
})
136 changes: 136 additions & 0 deletions test/integration-new/cni/env_vars/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package env_vars

import (
"regexp"

"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/onsi/ginkgo"
. "github.com/onsi/gomega"
)

const (
AWS_VPC_ENI_MTU = "AWS_VPC_ENI_MTU"
AWS_VPC_K8S_CNI_LOG_FILE = "AWS_VPC_K8S_CNI_LOG_FILE"
AWS_VPC_K8S_CNI_VETHPREFIX = "AWS_VPC_K8S_CNI_VETHPREFIX"
)

var _ = Describe("cni env test", func() {

Context("CNI Environment Variables", func() {
It("Verifying that secondary ENI is created", func() {
nodes, err := f.K8sResourceManagers.NodeManager().GetAllNodes()
Expect(err).NotTo(HaveOccurred())

for _, node := range nodes.Items {
instanceId := k8sUtils.GetInstanceIDFromNode(node)
instance, err := f.CloudServices.EC2().DescribeInstance(instanceId)
Expect(err).NotTo(HaveOccurred())

len := len(instance.NetworkInterfaces)
cgchinmay marked this conversation as resolved.
Show resolved Hide resolved
Expect(len).To(Equal(2))
}
})

It("Changing AWS_VPC_ENI_MTU and AWS_VPC_K8S_CNI_VETHPREFIX", func() {
currMTUVal := getEnvValueForKey(AWS_VPC_ENI_MTU)
cgchinmay marked this conversation as resolved.
Show resolved Hide resolved
Expect(currMTUVal).NotTo(Equal(""))

currVETHPrefix := getEnvValueForKey(AWS_VPC_K8S_CNI_VETHPREFIX)
Expect(currVETHPrefix).NotTo(Equal(""))

k8sUtils.AddEnvVarToDaemonSetAndWaitTillUpdated(f, DAEMONSET, NAMESPACE, DAEMONSET, map[string]string{
AWS_VPC_ENI_MTU: "1300",
AWS_VPC_K8S_CNI_VETHPREFIX: "veth",
})

By("Deploying a BusyBox deployment", func() {
cgchinmay marked this conversation as resolved.
Show resolved Hide resolved
deploymentSpec := manifest.NewBusyBoxDeploymentBuilder().
Namespace("default").
Name("busybox").
Replicas(1).
NodeName(primaryNode.Name).Build()

_, err := f.K8sResourceManagers.
DeploymentManager().
CreateAndWaitTillDeploymentIsReady(deploymentSpec)

Expect(err).ToNot(HaveOccurred())

stdout, _, err := f.K8sResourceManagers.PodManager().PodExec("default", hostNetworkPod.Name, []string{"ifconfig"})
cgchinmay marked this conversation as resolved.
Show resolved Hide resolved
Expect(err).NotTo(HaveOccurred())

re := regexp.MustCompile(`\n`)
input := re.ReplaceAllString(stdout, "")

re = regexp.MustCompile(`eth.*lo`)
eth := re.FindStringSubmatch(input)[0]

re = regexp.MustCompile(`MTU:[0-9]*`)
mtus := re.FindAllStringSubmatch(eth, -1)

By("Validating new MTU value", func() {
// Validate MTU
for _, m := range mtus {
Expect(m[0]).To(Equal("MTU:1300"))
}
})

By("Validating new VETH Prefix", func() {
// Validate VETH Prefix
// Adding the new MTU value to below regex ensures that we are checking the recently created
// veth and not any older entries
re = regexp.MustCompile(`veth.*MTU:1300`)
veth := re.FindAllString(input, -1)

Expect(len(veth)).NotTo(Equal(0))
})

By("Deleting BusyBox Deployment", func() {
err = f.K8sResourceManagers.DeploymentManager().DeleteAndWaitTillDeploymentIsDeleted(deploymentSpec)
Expect(err).NotTo(HaveOccurred())
})
})
restoreOldValues(map[string]string{
AWS_VPC_ENI_MTU: currMTUVal,
AWS_VPC_K8S_CNI_VETHPREFIX: currVETHPrefix,
})
})

It("Changing AWS_VPC_K8S_CNI_LOG_FILE", func() {
currLogFilepath := getEnvValueForKey(AWS_VPC_K8S_CNI_LOG_FILE)
Expect(currLogFilepath).NotTo(Equal(""))

newLogFile := "ipamd_test.log"
k8sUtils.AddEnvVarToDaemonSetAndWaitTillUpdated(f, DAEMONSET, NAMESPACE, DAEMONSET, map[string]string{
AWS_VPC_K8S_CNI_LOG_FILE: "/host/var/log/aws-routed-eni/" + newLogFile,
})

stdout, _, err := f.K8sResourceManagers.PodManager().PodExec("default", hostNetworkPod.Name, []string{"tail", "-n", "5", "ipamd-logs/ipamd_test.log"})
Expect(err).NotTo(HaveOccurred())

Expect(stdout).NotTo(Equal(""))

restoreOldValues(map[string]string{
AWS_VPC_K8S_CNI_LOG_FILE: currLogFilepath,
})
})
})
})

func getEnvValueForKey(key string) string {
envVar := ds.Spec.Template.Spec.Containers[0].Env
for _, env := range envVar {
if env.Name == key {
return env.Value
}
}
return ""
}

func restoreOldValues(oldVals map[string]string) {
By("Restoring old value on daemonset", func() {
k8sUtils.AddEnvVarToDaemonSetAndWaitTillUpdated(f, DAEMONSET, NAMESPACE, DAEMONSET, oldVals)
})
}