diff --git a/pkg/k8sclient/k8sclient.go b/pkg/k8sclient/k8sclient.go index 09fee7d89..e0f9e0d8b 100644 --- a/pkg/k8sclient/k8sclient.go +++ b/pkg/k8sclient/k8sclient.go @@ -114,11 +114,16 @@ func SetNetworkStatus(client *ClientInfo, k8sArgs *types.K8sArgs, netStatus []ne podName := string(k8sArgs.K8S_POD_NAME) podNamespace := string(k8sArgs.K8S_POD_NAMESPACE) + podUID := string(k8sArgs.K8S_POD_UID) pod, err := client.GetPod(podNamespace, podName) if err != nil { return logging.Errorf("SetNetworkStatus: failed to query the pod %v in out of cluster comm: %v", podName, err) } + if podUID != "" && string(pod.UID) != podUID { + return logging.Errorf("SetNetworkStatus: expected pod %s/%s UID %q but got %q from Kube API", podNamespace, podName, podUID, pod.UID) + } + if netStatus != nil { err = netutils.SetNetworkStatus(client.Client, pod, netStatus) if err != nil { diff --git a/pkg/k8sclient/k8sclient_test.go b/pkg/k8sclient/k8sclient_test.go index 1fbfe2fec..459bd74c3 100644 --- a/pkg/k8sclient/k8sclient_test.go +++ b/pkg/k8sclient/k8sclient_test.go @@ -55,6 +55,9 @@ var _ = Describe("k8sclient operations", func() { var tmpDir string var err error var genericConf string + var args *skel.CmdArgs + + const fakePodName string = "testPod" BeforeEach(func() { tmpDir, err = ioutil.TempDir("", "multus_tmp") @@ -69,6 +72,11 @@ var _ = Describe("k8sclient operations", func() { }], "kubeconfig":"/etc/kubernetes/node-kubeconfig.yaml" }` + + args = &skel.CmdArgs{ + // Values come from NewFakePod() + Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s;K8S_POD_UID=%s", fakePodName, "test", "testUID"), + } }) AfterEach(func() { @@ -77,7 +85,7 @@ var _ = Describe("k8sclient operations", func() { }) It("retrieves delegates from kubernetes using simple format annotation", func() { - fakePod := testutils.NewFakePod("testpod", "net1,net2", "") + fakePod := testutils.NewFakePod(fakePodName, "net1,net2", "") net1 := `{ "name": "net1", "type": "mynet", @@ -94,10 +102,6 @@ var _ = Describe("k8sclient operations", func() { "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -130,15 +134,12 @@ var _ = Describe("k8sclient operations", func() { }) It("fails when the network does not exist", func() { - fakePod := testutils.NewFakePod("testpod", "net1,net2", "") + fakePod := testutils.NewFakePod(fakePodName, "net1,net2", "") net3 := `{ "name": "net3", "type": "mynet3", "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -160,7 +161,7 @@ var _ = Describe("k8sclient operations", func() { }) It("retrieves delegates from kubernetes using JSON format annotation", func() { - fakePod := testutils.NewFakePod("testpod", `[ + fakePod := testutils.NewFakePod(fakePodName, `[ {"name":"net1"}, { "name":"net2", @@ -172,9 +173,6 @@ var _ = Describe("k8sclient operations", func() { "namespace":"other-ns" } ]`, "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -218,10 +216,7 @@ var _ = Describe("k8sclient operations", func() { }) It("fails when the JSON format annotation is invalid", func() { - fakePod := testutils.NewFakePod("testpod", "[adsfasdfasdfasf]", "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } + fakePod := testutils.NewFakePod(fakePodName, "[adsfasdfasdfasf]", "") clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -236,7 +231,7 @@ var _ = Describe("k8sclient operations", func() { }) It("can set the default-gateway on an additional interface", func() { - fakePod := testutils.NewFakePod("testpod", `[ + fakePod := testutils.NewFakePod(fakePodName, `[ {"name":"net1"}, { "name":"net2", @@ -247,9 +242,6 @@ var _ = Describe("k8sclient operations", func() { "namespace":"other-ns" } ]`, "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -294,10 +286,7 @@ var _ = Describe("k8sclient operations", func() { }) It("retrieves delegates from kubernetes using on-disk config files", func() { - fakePod := testutils.NewFakePod("testpod", "net1,net2", "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } + fakePod := testutils.NewFakePod(fakePodName, "net1,net2", "") clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -338,10 +327,7 @@ var _ = Describe("k8sclient operations", func() { }) It("injects network name into minimal thick plugin CNI config", func() { - fakePod := testutils.NewFakePod("testpod", "net1", "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } + fakePod := testutils.NewFakePod(fakePodName, "net1", "") clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -365,10 +351,7 @@ var _ = Describe("k8sclient operations", func() { }) It("fails when on-disk config file is not valid", func() { - fakePod := testutils.NewFakePod("testpod", "net1,net2", "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } + fakePod := testutils.NewFakePod(fakePodName, "net1,net2", "") clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -399,7 +382,7 @@ var _ = Describe("k8sclient operations", func() { }) It("retrieves cluster network from CRD", func() { - fakePod := testutils.NewFakePod("testpod", "", "") + fakePod := testutils.NewFakePod(fakePodName, "", "") conf := `{ "name":"node-cni-network", "type":"multus", @@ -409,10 +392,6 @@ var _ = Describe("k8sclient operations", func() { netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -431,7 +410,7 @@ var _ = Describe("k8sclient operations", func() { }) It("retrieves default networks from CRD", func() { - fakePod := testutils.NewFakePod("testpod", "", "") + fakePod := testutils.NewFakePod(fakePodName, "", "") conf := `{ "name":"node-cni-network", "type":"multus", @@ -442,10 +421,6 @@ var _ = Describe("k8sclient operations", func() { netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -469,7 +444,7 @@ var _ = Describe("k8sclient operations", func() { }) It("ignore default networks from CRD in case of kube-system namespace", func() { - fakePod := testutils.NewFakePod("testpod", "", "") + fakePod := testutils.NewFakePod(fakePodName, "", "") // overwrite namespace fakePod.ObjectMeta.Namespace = "kube-system" conf := `{ @@ -482,10 +457,6 @@ var _ = Describe("k8sclient operations", func() { netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -507,7 +478,7 @@ var _ = Describe("k8sclient operations", func() { }) It("retrieves cluster network from file", func() { - fakePod := testutils.NewFakePod("testpod", "", "") + fakePod := testutils.NewFakePod(fakePodName, "", "") conf := `{ "name":"node-cni-network", "type":"multus", @@ -518,10 +489,6 @@ var _ = Describe("k8sclient operations", func() { netConf.ConfDir = tmpDir Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -546,7 +513,7 @@ var _ = Describe("k8sclient operations", func() { }) It("retrieves cluster network from path", func() { - fakePod := testutils.NewFakePod("testpod", "", "") + fakePod := testutils.NewFakePod(fakePodName, "", "") conf := fmt.Sprintf(`{ "name":"node-cni-network", "type":"multus", @@ -556,10 +523,6 @@ var _ = Describe("k8sclient operations", func() { netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -582,7 +545,7 @@ var _ = Describe("k8sclient operations", func() { }) It("Error in case of CRD not found", func() { - fakePod := testutils.NewFakePod("testpod", "", "") + fakePod := testutils.NewFakePod(fakePodName, "", "") conf := `{ "name":"node-cni-network", "type":"multus", @@ -592,10 +555,6 @@ var _ = Describe("k8sclient operations", func() { netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -608,7 +567,7 @@ var _ = Describe("k8sclient operations", func() { }) It("overwrite cluster network when Pod annotation is set", func() { - fakePod := testutils.NewFakePod("testpod", "", "net1") + fakePod := testutils.NewFakePod(fakePodName, "", "net1") conf := `{ "name":"node-cni-network", "type":"multus", @@ -619,10 +578,6 @@ var _ = Describe("k8sclient operations", func() { netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -650,7 +605,7 @@ var _ = Describe("k8sclient operations", func() { }) It("fails with bad confdir", func() { - fakePod := testutils.NewFakePod("testpod", "", "net1") + fakePod := testutils.NewFakePod(fakePodName, "", "net1") conf := `{ "name":"node-cni-network", "type":"multus", @@ -661,10 +616,6 @@ var _ = Describe("k8sclient operations", func() { netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -686,7 +637,7 @@ var _ = Describe("k8sclient operations", func() { It("overwrite multus config when Pod annotation is set", func() { - fakePod := testutils.NewFakePod("testpod", "", "net1") + fakePod := testutils.NewFakePod(fakePodName, "", "net1") conf := `{ "name":"node-cni-network", "type":"multus", @@ -701,10 +652,6 @@ var _ = Describe("k8sclient operations", func() { Expect(netConf.Delegates[0].Conf.Type).To(Equal("mynet2")) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -723,7 +670,7 @@ var _ = Describe("k8sclient operations", func() { }) It("fails with no kubeclient and invalid kubeconfig", func() { - fakePod := testutils.NewFakePod("testpod", "", "net1") + fakePod := testutils.NewFakePod(fakePodName, "", "net1") conf := `{ "name":"node-cni-network", "type":"multus", @@ -738,10 +685,6 @@ var _ = Describe("k8sclient operations", func() { Expect(netConf.Delegates[0].Conf.Type).To(Equal("mynet2")) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -757,7 +700,7 @@ var _ = Describe("k8sclient operations", func() { }) It("fails with no kubeclient and no kubeconfig", func() { - fakePod := testutils.NewFakePod("testpod", "", "net1") + fakePod := testutils.NewFakePod(fakePodName, "", "net1") conf := `{ "name":"node-cni-network", "type":"multus", @@ -772,10 +715,6 @@ var _ = Describe("k8sclient operations", func() { Expect(netConf.Delegates[0].Conf.Type).To(Equal("mynet2")) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -821,7 +760,7 @@ users: client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBMUxyZmUxaXNQaTNDYng4eHRDWG1QTlE2L0xXYVVEa1ZRNVBkdGtQK3dVYmdJUFJ6CmNtRzNEcnUya0kvamsxMGQzaUgzOVZlZDlHVjczbnZyVm5Id0pzZEF5QzVmYlRTQVBUVVNJOW90MVFGbENRUGcKQ2JLbjBRbmxUeUhXMmNnTis2Q3BWK0U4dFpWajJ2cDZoTDlmR0s2bUJCL2I4VFN3RmYxRmtnWC9hTGN1emZDaApmVFNDOWlRTk15cEFjamZadEkzWiszbHVzSVB6TVpBNTZPZXNodzlnRkJHUkw3RzZHWmZKcG9OaGVxTDlmandUClRkNURlbVZXcUxUR05ZNWhhV3hicy9VbThuM0QvdlV1QkVPYTYxQ2cvcGljUkU3Um14SmFJRWJiQlNTV1dkSDMKWDlrem5RdHJrUXloL28xZnpSV1pxeWFCY3hxR1FWN0JSSzFtSndJREFRQUJBb0lCQUJ0bjA4QzFSTU5oNjhtYgpFREV3TE1BcmEwb0JMMWNrYzN2WVFkam9XNXFVd2UwYzhQNk1YaVAweE9sTTBEbTg1a3NtdnlZSldwMFFzZXVRCnRWbldwZVNwQ015QlJPUHh2bytrRmFrdXczYk1qaktpSUN1L3EyVC96RjNzY3h4dGJIZTlVL094WGJ2YStobE0KNlpuT2ViYlpVU1A0NHNIcFVzSVNkZk1BK00ySmg1UFJibGZWaUFEY1hxNFR5RU1JaStzRkhOcFIrdmdWZzRFawp4RmFVaS83V0E2YUxWVzBUTzREdjMwbTJ0TVczWXN1bk1LTU0xOTNyUEZrU0dEdFpheWV2Z0JDeURXaFhOTEo2Clh1cTNxSUg4bFE2bzRBUjMvcDc1ZW9hOCtrVzVmT3o2UWF3WnpPYlBENkRCQlVOYVM1YklXaVV1dmx5L0JlM20KZnlxK3NRRUNnWUVBMW84R3l6ODk2bFhwdU1yVXVsb2orbGp5U0FaNkpLOCsyaFMvQnpyREx6NlpvY3FzKzg3awpVUkwzKy9LL1pja2pIMVVDeXROVVZ6Q3RKaG4zZmdLS2dpQWhsU0pNRzhqc05sbEkydFZSazNZZ1RCcUg2bXZxCit3citsTUxoUDZxbWFObUx3QXljY2lEanpMdXlRdjhVOFhKazJOdVFsQlFwbkt2eWJIRGdxSUVDZ1lFQS9kRnMKazNlYmRNNFAxV2psYXJoRTV5blpuRmdQbDg1L2Vudk4rQ1oxcStlMGxYendaUGswdWdJUWozYyt2UEpLWlh0OApLWk1HQjM0N2VLNlFIL3J1a2xRWXlLOStHeUV1YnRJQUZ2NWFrYXZxV1haR1p5ZC9QdDR1V09adXMrd3BnSG00CkxFY0lzZElsYkpFY2RJTzJyb3FaY0VNY3FEbGtXcTdwQWxqU2VxY0NnWUJYdUQ0RTFxUlByRFJVRXNrS0wxUksKUkJjNkR6dmN4N0VncEI2OXErNms0Q2tibHF0R2YvMmtqK2JISVNYVFRYcUlrczhEY1ljbjVvVEQ4UlhZZE4xLworZmNBNi9iRjNVMkZvdGRBY0xwYldZNDJ6eG9HWTN5OGluQXZEY1hkcTcxQlhML2dFc2ZiZVVycEowdm9URFdaCnlUVWwzQTZ1RzlndmI3VTdWS0xsQVFLQmdBTmNscmVOU2YzT0ROK2l1QWNsMGFQT0poZXdBdVRiMDB4bi8xNWUKQkFqMjFLbDJNaWprTkJLU25HMktBc2ExM3M1aFNFKzBwc3ZLbkRjSStOZXpseDFSQjlNQW9BYno5WTE2TW80YgphRSt0bXpqOEhBcVp0MUc1MTV0TjBnR0lDelNzYUFnT0dNdGlJU1RDOTBHRHpST2F1bFdHVGdiY1c3dm52U1pPCnp0clpBb0dBWmtIRWV5em16Z2cxR3dtTzN3bmljSHRMR1BQRFhiSW53NTdsdkIrY3lyd0FrVEs1MlFScTM0VkMKRDhnQWFwMTU2OWlWUER3YlgrNkpBQk1WQ2tNUmdxMjdHanUzN0pVY2Fib2g1YzJQeTBYNUlhUG8rek1hWHgvQwpqbjUvUW5YandjU1MrRU5hL1lXVWcxWEVjQjJYdEM0UExCdGUycitrUTVLbFNOREcxSTQ9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==` kubeletconf.Write([]byte(kubeletconfDef)) - fakePod := testutils.NewFakePod("testpod", "", "net1") + fakePod := testutils.NewFakePod(fakePodName, "", "net1") conf := fmt.Sprintf(`{ "name":"node-cni-network", "type":"multus", @@ -836,10 +775,6 @@ users: Expect(netConf.Delegates[0].Conf.Type).To(Equal("mynet2")) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -854,7 +789,7 @@ users: }) It("Errors when namespace isolation is violated", func() { - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") conf := `{ "name":"node-cni-network", "type":"multus", @@ -875,10 +810,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -902,7 +833,7 @@ users: }) It("Properly allows a specified namespace reference when namespace isolation is enabled", func() { - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") conf := `{ "name":"node-cni-network", "type":"multus", @@ -924,10 +855,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -958,7 +885,7 @@ users: Context("getDefaultNetDelegateCRD", func() { It("fails when netConf contains bad confDir", func() { - fakePod := testutils.NewFakePod("testpod", "", "net1") + fakePod := testutils.NewFakePod(fakePodName, "", "net1") conf := `{ "name":"node-cni-network", "type":"multus", @@ -969,10 +896,6 @@ users: netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -992,9 +915,9 @@ users: Context("GetK8sArgs", func() { It("fails when provided with bad format", func() { - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME:%s;K8S_POD_NAMESPACE:%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") + args = &skel.CmdArgs{ + Args: fmt.Sprintf("K8S_POD_NAME:%s;K8S_POD_NAMESPACE:%s;K8S_POD_UID:%s", fakePod.Name, fakePod.Namespace, fakePod.UID), } // using colon instead of equals sign makes an invalid CmdArgs @@ -1005,7 +928,7 @@ users: Context("getKubernetesDelegate", func() { It("failed to get a ResourceClient instance", func() { - fakePod := testutils.NewFakePod("testpod", "net1,net2", "") + fakePod := testutils.NewFakePod(fakePodName, "net1,net2", "") net1 := `{ "name": "net1", "type": "mynet", @@ -1021,9 +944,6 @@ users: "type": "mynet3", "cniVersion": "0.2.0" }` - // args := &skel.CmdArgs{ - // Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - // } clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -1051,10 +971,7 @@ users: Context("parsePodNetworkObjectName", func() { It("fails to get podnetwork given bad annotation values", func() { - fakePod := testutils.NewFakePod("testpod", "net1", "") - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } + fakePod := testutils.NewFakePod(fakePodName, "net1", "") clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) @@ -1087,7 +1004,7 @@ users: Context("setPodNetworkAnnotation", func() { It("Sets pod network annotations without error", func() { - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") net1 := `{ "name": "net1", @@ -1095,10 +1012,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -1172,10 +1085,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err := clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -1183,6 +1092,9 @@ users: _, err = clientInfo.AddNetAttachDef(testutils.NewFakeNetAttachDef("kube-system", "net1", net1)) Expect(err).NotTo(HaveOccurred()) + args = &skel.CmdArgs{ + Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s;K8S_POD_UID=%s", fakePod.Name, fakePod.Namespace, "blahblah"), + } k8sArgs, err := GetK8sArgs(args) Expect(err).NotTo(HaveOccurred()) @@ -1209,7 +1121,7 @@ users: // TODO Still figuring this next one out. deals with exponentialBackoff // It("Fails to set pod network annotations without error", func() { - // fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + // fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") // net1 := `{ // "name": "net1", @@ -1217,10 +1129,6 @@ users: // "cniVersion": "0.2.0" // }` - // args := &skel.CmdArgs{ - // Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - // } - // clientInfo := NewFakeClientInfo() // _, err := clientInfo.AddPod(fakePod) // Expect(err).NotTo(HaveOccurred()) @@ -1240,7 +1148,7 @@ users: }) Context("SetNetworkStatus", func() { - It("Sets network status without error", func() { + It("Sets network status without error when pod UIDs match", func() { result := &types020.Result{ CNIVersion: "0.2.0", IP4: &types020.IPConfig{ @@ -1271,7 +1179,7 @@ users: netstatus := []nettypes.NetworkStatus{*delegateNetStatus} - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) @@ -1282,10 +1190,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -1299,6 +1203,123 @@ users: Expect(err).NotTo(HaveOccurred()) }) + It("Sets pod network annotations without error when runtime does not provide a pod UID", func() { + result := &types020.Result{ + CNIVersion: "0.2.0", + IP4: &types020.IPConfig{ + IP: *testutils.EnsureCIDR("1.1.1.2/24"), + }, + } + + conf := `{ + "name": "node-cni-network", + "type": "multus", + "kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml", + "delegates": [{ + "type": "weave-net" + }], + "runtimeConfig": { + "portMappings": [ + {"hostPort": 8080, "containerPort": 80, "protocol": "tcp"} + ] + } + }` + + delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") + Expect(err).NotTo(HaveOccurred()) + + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) + GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) + Expect(err).NotTo(HaveOccurred()) + + netstatus := []nettypes.NetworkStatus{*delegateNetStatus} + + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") + + netConf, err := types.LoadNetConf([]byte(conf)) + Expect(err).NotTo(HaveOccurred()) + + net1 := `{ + "name": "net1", + "type": "mynet", + "cniVersion": "0.2.0" + }` + + clientInfo := NewFakeClientInfo() + _, err = clientInfo.AddPod(fakePod) + Expect(err).NotTo(HaveOccurred()) + _, err = clientInfo.AddNetAttachDef(testutils.NewFakeNetAttachDef("kube-system", "net1", net1)) + Expect(err).NotTo(HaveOccurred()) + + args = &skel.CmdArgs{ + Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.Name, fakePod.Namespace), + } + k8sArgs, err := GetK8sArgs(args) + Expect(err).NotTo(HaveOccurred()) + + err = SetNetworkStatus(clientInfo, k8sArgs, netstatus, netConf) + Expect(err).NotTo(HaveOccurred()) + }) + + It("Fails to set pod network annotations when pod UIDs don't match", func() { + result := &types020.Result{ + CNIVersion: "0.2.0", + IP4: &types020.IPConfig{ + IP: *testutils.EnsureCIDR("1.1.1.2/24"), + }, + } + + conf := `{ + "name": "node-cni-network", + "type": "multus", + "kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml", + "delegates": [{ + "type": "weave-net" + }], + "runtimeConfig": { + "portMappings": [ + {"hostPort": 8080, "containerPort": 80, "protocol": "tcp"} + ] + } + }` + + delegate, err := types.LoadDelegateNetConf([]byte(conf), nil, "0000:00:00.0", "") + Expect(err).NotTo(HaveOccurred()) + + delegateNetStatus, err := netutils.CreateNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin, nil) + GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus) + Expect(err).NotTo(HaveOccurred()) + + netstatus := []nettypes.NetworkStatus{*delegateNetStatus} + + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") + + netConf, err := types.LoadNetConf([]byte(conf)) + Expect(err).NotTo(HaveOccurred()) + + net1 := `{ + "name": "net1", + "type": "mynet", + "cniVersion": "0.2.0" + }` + + clientInfo := NewFakeClientInfo() + _, err = clientInfo.AddPod(fakePod) + Expect(err).NotTo(HaveOccurred()) + _, err = clientInfo.AddNetAttachDef(testutils.NewFakeNetAttachDef("kube-system", "net1", net1)) + Expect(err).NotTo(HaveOccurred()) + + args = &skel.CmdArgs{ + Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s;K8S_POD_UID=%s", fakePod.Name, fakePod.Namespace, "foobar"), + } + k8sArgs, err := GetK8sArgs(args) + Expect(err).NotTo(HaveOccurred()) + + err = SetNetworkStatus(clientInfo, k8sArgs, netstatus, netConf) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf("expected pod %s/%s UID %q but got %q from Kube API", + fakePod.Namespace, fakePod.Name, string(k8sArgs.K8S_POD_UID), fakePod.UID))) + }) + It("Sets network status with kubeclient built from kubeconfig and attempts to connect", func() { kubeletconf, err := os.Create("/etc/kubernetes/kubelet.conf") kubeletconfDef := `apiVersion: v1 @@ -1353,7 +1374,7 @@ users: netstatus := []nettypes.NetworkStatus{*delegateNetStatus} - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) @@ -1364,10 +1385,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -1413,7 +1430,7 @@ users: netstatus := []nettypes.NetworkStatus{*delegateNetStatus} - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) @@ -1424,10 +1441,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) @@ -1472,7 +1485,7 @@ users: netstatus := []nettypes.NetworkStatus{*delegateNetStatus} - fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "") + fakePod := testutils.NewFakePod(fakePodName, "kube-system/net1", "") netConf, err := types.LoadNetConf([]byte(conf)) Expect(err).NotTo(HaveOccurred()) @@ -1483,10 +1496,6 @@ users: "cniVersion": "0.2.0" }` - args := &skel.CmdArgs{ - Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace), - } - clientInfo := NewFakeClientInfo() _, err = clientInfo.AddPod(fakePod) Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/multus/multus.go b/pkg/multus/multus.go index deeb6923e..08059f1a2 100644 --- a/pkg/multus/multus.go +++ b/pkg/multus/multus.go @@ -496,7 +496,7 @@ func delPlugins(exec invoke.Exec, pod *v1.Pod, args *skel.CmdArgs, k8sArgs *type func cmdErr(k8sArgs *types.K8sArgs, format string, args ...interface{}) error { prefix := "Multus: " if k8sArgs != nil { - prefix += fmt.Sprintf("[%s/%s]: ", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME) + prefix += fmt.Sprintf("[%s/%s/%s]: ", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME, k8sArgs.K8S_POD_UID) } return logging.Errorf(prefix+format, args...) } @@ -504,7 +504,7 @@ func cmdErr(k8sArgs *types.K8sArgs, format string, args ...interface{}) error { func cmdPluginErr(k8sArgs *types.K8sArgs, confName string, format string, args ...interface{}) error { msg := "" if k8sArgs != nil { - msg += fmt.Sprintf("[%s/%s:%s]: ", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME, confName) + msg += fmt.Sprintf("[%s/%s/%s:%s]: ", k8sArgs.K8S_POD_NAMESPACE, k8sArgs.K8S_POD_NAME, k8sArgs.K8S_POD_UID, confName) } return logging.Errorf(msg+format, args...) } @@ -521,6 +521,43 @@ func isCriticalRequestRetriable(err error) bool { return false } +func getPod(kubeClient *k8s.ClientInfo, k8sArgs *types.K8sArgs, ignoreNotFound bool) (*v1.Pod, error) { + if kubeClient == nil { + return nil, nil + } + + podNamespace := string(k8sArgs.K8S_POD_NAMESPACE) + podName := string(k8sArgs.K8S_POD_NAME) + podUID := string(k8sArgs.K8S_POD_UID) + + pod, err := kubeClient.GetPod(podNamespace, podName) + if err != nil { + // in case of a retriable error, retry 10 times with 0.25 sec interval + if isCriticalRequestRetriable(err) { + waitErr := wait.PollImmediate(shortPollDuration, shortPollTimeout, func() (bool, error) { + pod, err = kubeClient.GetPod(podNamespace, podName) + return pod != nil, err + }) + // retry failed, then return error with retry out + if waitErr != nil { + return nil, cmdErr(k8sArgs, "error waiting for pod: %v", err) + } + } else if ignoreNotFound && errors.IsNotFound(err) { + // If not found, proceed to remove interface with cache + return nil, nil + } else { + // Other case, return error + return nil, cmdErr(k8sArgs, "error getting pod: %v", err) + } + } + + if podUID != "" && string(pod.UID) != podUID { + return nil, cmdErr(k8sArgs, "expected pod UID %q but got %q from Kube API", podUID, pod.UID) + } + + return pod, nil +} + //CmdAdd ... func CmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (cnitypes.Result, error) { n, err := types.LoadNetConf(args.StdinData) @@ -549,26 +586,9 @@ func CmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) (c } } - pod := (*v1.Pod)(nil) - if kubeClient != nil { - pod, err = kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME)) - if err != nil { - var waitErr error - // in case of a retriable error, retry 10 times with 0.25 sec interval - if isCriticalRequestRetriable(err) { - waitErr = wait.PollImmediate(shortPollDuration, shortPollTimeout, func() (bool, error) { - pod, err = kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME)) - return pod != nil, err - }) - // retry failed, then return error with retry out - if waitErr != nil { - return nil, cmdErr(k8sArgs, "error getting pod with error: %v", err) - } - } else { - // Other case, return error - return nil, cmdErr(k8sArgs, "error getting pod: %v", err) - } - } + pod, err := getPod(kubeClient, k8sArgs, false) + if err != nil { + return nil, err } // resourceMap holds Pod device allocation information; only initizized if CRD contains 'resourceName' annotation. @@ -774,29 +794,9 @@ func CmdDel(args *skel.CmdArgs, exec invoke.Exec, kubeClient *k8s.ClientInfo) er return cmdErr(nil, "error getting k8s client: %v", err) } - pod := (*v1.Pod)(nil) - if kubeClient != nil { - pod, err = kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME)) - if err != nil { - var waitErr error - // in case of a retriable error, retry 10 times with 0.25 sec interval - if isCriticalRequestRetriable(err) { - waitErr = wait.PollImmediate(shortPollDuration, shortPollTimeout, func() (bool, error) { - pod, err = kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME)) - return pod != nil, err - }) - // retry failed, then return error with retry out - if waitErr != nil { - return cmdErr(k8sArgs, "error getting pod with error: %v", err) - } - } else if errors.IsNotFound(err) { - // If not found, proceed to remove interface with cache - pod = nil - } else { - // Other case, return error - return cmdErr(k8sArgs, "error getting pod: %v", err) - } - } + pod, err := getPod(kubeClient, k8sArgs, true) + if err != nil { + return err } // Read the cache to get delegates json for the pod diff --git a/pkg/multus/multus_test.go b/pkg/multus/multus_test.go index 484925413..c5934322f 100644 --- a/pkg/multus/multus_test.go +++ b/pkg/multus/multus_test.go @@ -1236,7 +1236,7 @@ var _ = Describe("multus operations cniVersion 0.2.0 config", func() { _, err = CmdAdd(args, fExec, nil) Expect(fExec.addIndex).To(Equal(2)) Expect(fExec.delIndex).To(Equal(2)) - Expect(err).To(MatchError("[/:other1]: error adding container to network \"other1\": expected plugin failure")) + Expect(err).To(MatchError("[//:other1]: error adding container to network \"other1\": expected plugin failure")) // Cleanup default network file. if _, errStat := os.Stat(configPath); errStat == nil { @@ -1420,6 +1420,116 @@ var _ = Describe("multus operations cniVersion 0.2.0 config", func() { Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue()) }) + It("fails when pod UID is provided and does not match Kube API pod UID", func() { + fakePod := testhelpers.NewFakePod("testpod", "net1", "") + net1 := `{ + "name": "net1", + "type": "mynet", + "capabilities": {"mac": true, "ips": true, "bandwidth": true, "portMappings": true}, + "cniVersion": "0.3.1" + }` + args := &skel.CmdArgs{ + ContainerID: "123456789", + Netns: testNS.Path(), + IfName: "eth0", + Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s;K8S_POD_UID=foobar", fakePod.Name, fakePod.Namespace), + StdinData: []byte(`{ + "name": "node-cni-network", + "type": "multus", + "kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml", + "delegates": [{ + "name": "weave1", + "cniVersion": "0.3.1", + "type": "weave-net" + }] + }`), + } + + clientInfo := NewFakeClientInfo() + _, err := clientInfo.Client.CoreV1().Pods(fakePod.Namespace).Create( + context.TODO(), fakePod, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + _, err = clientInfo.AddNetAttachDef( + testhelpers.NewFakeNetAttachDef(fakePod.Namespace, "net1", net1)) + Expect(err).NotTo(HaveOccurred()) + + os.Setenv("CNI_COMMAND", "ADD") + os.Setenv("CNI_IFNAME", "eth0") + _, err = CmdAdd(args, &fakeExec{}, clientInfo) + Expect(err.Error()).To(ContainSubstring("expected pod UID \"foobar\" but got %q from Kube API", fakePod.UID)) + }) + + It("executes delegates when runtime provides a matching pod UID", func() { + fakePod := testhelpers.NewFakePod("testpod", "net1", "") + net1 := `{ + "name": "net1", + "type": "mynet", + "cniVersion": "0.3.1" + }` + args := &skel.CmdArgs{ + ContainerID: "123456789", + Netns: testNS.Path(), + IfName: "eth0", + Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s;K8S_POD_UID=%s", fakePod.Name, fakePod.Namespace, fakePod.UID), + StdinData: []byte(`{ + "name": "node-cni-network", + "type": "multus", + "kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml", + "delegates": [{ + "name": "weave1", + "cniVersion": "0.3.1", + "type": "weave-net" + }] + }`), + } + + fExec := &fakeExec{} + expectedResult1 := ¤t.Result{ + CNIVersion: resultCNIVersion, + IPs: []*current.IPConfig{{ + Address: *testhelpers.EnsureCIDR("1.1.1.2/24"), + }, + }, + } + expectedConf1 := `{ + "name": "weave1", + "cniVersion": "0.3.1", + "type": "weave-net" + }` + expectedNet1 := `{ + "name": "net1", + "type": "mynet", + "cniVersion": "0.3.1" + }` + fExec.addPlugin(nil, "eth0", expectedConf1, expectedResult1, nil) + fExec.addPlugin(nil, "net1", expectedNet1, ¤t.Result{ + CNIVersion: "0.3.1", + IPs: []*current.IPConfig{{ + Address: *testhelpers.EnsureCIDR("1.1.1.3/24"), + }, + }, + }, nil) + + clientInfo := NewFakeClientInfo() + _, err := clientInfo.Client.CoreV1().Pods(fakePod.ObjectMeta.Namespace).Create( + context.TODO(), fakePod, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred()) + + _, err = clientInfo.AddNetAttachDef( + testhelpers.NewFakeNetAttachDef(fakePod.ObjectMeta.Namespace, "net1", net1)) + Expect(err).NotTo(HaveOccurred()) + + os.Setenv("CNI_COMMAND", "ADD") + os.Setenv("CNI_IFNAME", "eth0") + result, err := CmdAdd(args, fExec, clientInfo) + Expect(err).NotTo(HaveOccurred()) + Expect(fExec.addIndex).To(Equal(len(fExec.plugins))) + r := result.(*current.Result) + // plugin 1 is the masterplugin + Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue()) + }) + It("executes delegates and kubernetes networks with events check", func() { fakePod := testhelpers.NewFakePod("testpod", "net1,net2", "") net1 := `{ @@ -2486,7 +2596,7 @@ var _ = Describe("multus operations cniVersion 0.4.0 config", func() { _, err = CmdAdd(args, fExec, nil) Expect(fExec.addIndex).To(Equal(2)) Expect(fExec.delIndex).To(Equal(2)) - Expect(err).To(MatchError("[/:other1]: error adding container to network \"other1\": expected plugin failure")) + Expect(err).To(MatchError("[//:other1]: error adding container to network \"other1\": expected plugin failure")) // Cleanup default network file. if _, errStat := os.Stat(configPath); errStat == nil { diff --git a/pkg/types/conf.go b/pkg/types/conf.go index d399edce6..ab36ccf25 100644 --- a/pkg/types/conf.go +++ b/pkg/types/conf.go @@ -204,8 +204,6 @@ func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, r } // In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go#buildCNIRuntimeConf - // Todo - // ingress, egress and bandwidth capability features as same as kubelet. rt := &libcni.RuntimeConf{ ContainerID: args.ContainerID, NetNS: args.Netns, @@ -216,6 +214,7 @@ func CreateCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, r {"K8S_POD_NAMESPACE", string(k8sArgs.K8S_POD_NAMESPACE)}, {"K8S_POD_NAME", string(k8sArgs.K8S_POD_NAME)}, {"K8S_POD_INFRA_CONTAINER_ID", string(k8sArgs.K8S_POD_INFRA_CONTAINER_ID)}, + {"K8S_POD_UID", string(k8sArgs.K8S_POD_UID)}, }, } diff --git a/pkg/types/types.go b/pkg/types/types.go index 9330db756..e3f6e8ea7 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -157,6 +157,7 @@ type K8sArgs struct { K8S_POD_NAME types.UnmarshallableString //revive:disable-line K8S_POD_NAMESPACE types.UnmarshallableString //revive:disable-line K8S_POD_INFRA_CONTAINER_ID types.UnmarshallableString //revive:disable-line + K8S_POD_UID types.UnmarshallableString //revive:disable-line } // ResourceInfo is struct to hold Pod device allocation information