diff --git a/pkg/types/conf.go b/pkg/types/conf.go index f6d66c51f..36637875c 100644 --- a/pkg/types/conf.go +++ b/pkg/types/conf.go @@ -219,29 +219,33 @@ func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, r }, } - // get CNI_ARGS and set it if it does not exist in rt.Args + // Populate rt.Args with CNI_ARGS if the rt.Args value is not set cniArgs := os.Getenv("CNI_ARGS") if cniArgs != "" { for _, arg := range strings.Split(cniArgs, ";") { - for _, keyval := range strings.Split(arg, "=") { - if len(keyval) != 2 { - logging.Errorf("CreateCNIRuntimeConf: CNI_ARGS %s %s %d is not recognized as CNI arg, skipped", arg, keyval, len(keyval)) - continue - } + // SplitN to handle = within values, like BLAH=foo=bar + keyval := strings.SplitN(arg, "=", 2) + if len(keyval) != 2 { + logging.Errorf("CreateCNIRuntimeConf: CNI_ARGS %s %s %d is not recognized as CNI arg, skipped", arg, keyval, len(keyval)) + continue + } - envKey := string(keyval[0]) - envVal := string(keyval[1]) - isExists := false - for _, rtArg := range rt.Args { - if rtArg[0] == envKey { - isExists = true - } - } - if isExists != false { + envKey := string(keyval[0]) + envVal := string(keyval[1]) + found := false + for i := range rt.Args { + // Update existing key if its value is empty + if rt.Args[i][0] == envKey && rt.Args[i][1] == "" && envVal != "" { logging.Debugf("CreateCNIRuntimeConf: add new val: %s", arg) - rt.Args = append(rt.Args, [2]string{envKey, envVal}) + rt.Args[i][1] = envVal + found = true + break } } + if !found { + // Add the new key if it didn't exist yet + rt.Args = append(rt.Args, [2]string{envKey, envVal}) + } } } diff --git a/pkg/types/conf_test.go b/pkg/types/conf_test.go index b155ef7eb..960e65adf 100644 --- a/pkg/types/conf_test.go +++ b/pkg/types/conf_test.go @@ -56,6 +56,7 @@ var _ = Describe("config operations", func() { AfterEach(func() { Expect(testNS.Close()).To(Succeed()) os.Unsetenv("CNI_PATH") + os.Unsetenv("CNI_ARGS") err := os.RemoveAll(tmpDir) Expect(err).NotTo(HaveOccurred()) }) @@ -639,6 +640,44 @@ var _ = Describe("config operations", func() { Expect(rt.CapabilityArgs["portMappings"]).To(Equal(rc.PortMaps)) }) + It("creates a valid CNI runtime config with K8s args passed via CNI_ARGS environment variable", func() { + args := &skel.CmdArgs{ + ContainerID: "123456789", + Netns: testNS.Path(), + IfName: "eth0", + StdinData: []byte(`{ + "name": "node-cni-network", + "type": "multus", + "defaultnetworkfile": "/tmp/foo.multus.conf", + "defaultnetworkwaitseconds": 3, + "delegates": [{ + "name": "weave1", + "cniVersion": "0.2.0", + "type": "weave-net" + },{ + "name": "other1", + "cniVersion": "0.2.0", + "type": "other-plugin" + }] +}`), + } + + os.Setenv("CNI_ARGS", "K8S_POD_NAME=dummy;K8S_POD_NAMESPACE=namespacedummy;K8S_POD_INFRA_CONTAINER_ID=123456789;K8S_POD_UID=aaaaa;BLAHBLAH=foo=bar") + k8sArgs := &K8sArgs{} + rt, _ := CreateCNIRuntimeConf(args, k8sArgs, "", &RuntimeConfig{}, nil) + fmt.Println("rt.ContainerID: ", rt.ContainerID) + Expect(rt.ContainerID).To(Equal("123456789")) + Expect(rt.NetNS).To(Equal(args.Netns)) + Expect(rt.IfName).To(Equal("")) + fmt.Println("rt.ContainerID: ", rt.ContainerID) + Expect(rt.Args[0]).To(Equal([2]string{"IgnoreUnknown", "true"})) + Expect(rt.Args[1]).To(Equal([2]string{"K8S_POD_NAMESPACE", "namespacedummy"})) + Expect(rt.Args[2]).To(Equal([2]string{"K8S_POD_NAME", "dummy"})) + Expect(rt.Args[3]).To(Equal([2]string{"K8S_POD_INFRA_CONTAINER_ID", "123456789"})) + Expect(rt.Args[4]).To(Equal([2]string{"K8S_POD_UID", "aaaaa"})) + Expect(rt.Args[5]).To(Equal([2]string{"BLAHBLAH", "foo=bar"})) + }) + It("can loadnetworkstatus", func() { result := &types020.Result{ CNIVersion: "0.2.0",