types: fix usage of strings.Split() for parsing CNI_ARGS (#836)

* types: fix usage of strings.Split() for parsing CNI_ARGS

strings.Split() returns a slice, in this case with two elements of
the key and value. As such we shouldn't range over the slice when
the code is expecting a 2-element slice of key/value.

Otherwise we get errors for valid CNI_ARGS like:

2022-04-22T11:53:54Z [error] CreateCNIRuntimeConf: CNI_ARGS K8S_POD_NAMESPACE=openshift-etcd K8S_POD_NAMESPACE 17 is not recognized as CNI arg, skipped
2022-04-22T11:53:54Z [error] CreateCNIRuntimeConf: CNI_ARGS K8S_POD_NAMESPACE=openshift-etcd openshift-etcd 14 is not recognized as CNI arg, skipped

Fixes: d7d2a99ab5 ("Replace setenv with runtimeConfig set")

Signed-off-by: Dan Williams <dcbw@redhat.com>

* types/conf: fix handling of CNI_ARGS additions to rt.Args

We want to set the CNI_ARGS value in rt.Args if the existing value
is empty, not if the key doesn't exist yet. Since the rt.Args array
is pre-created with the K8S args keys, empty values of those keys
couldn't be overwritten with the previous scheme that just checked
if the key existed.

If the CNI_ARGS key wasn't found in rt.Args then add it; previously
a typo ("isExists != false") prevented that with inverted logic.

Signed-off-by: Dan Williams <dcbw@redhat.com>
This commit is contained in:
Dan Williams
2022-04-25 10:13:09 -05:00
committed by GitHub
parent dd15abc9b1
commit ecc1482d50
2 changed files with 59 additions and 16 deletions

View File

@@ -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})
}
}
}

View File

@@ -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",