forked from github/multus-cni
Unit tests and update to quickstart guide (#354)
* Added a test for GetLoggingLevel * Added up to 96% coverage for checkpoint.go * Improved coverage of checkpoint.go to 96.4% * Improved coverage of checkpoint.go to 96.4% * Adding changes so i will have them saved for my remote fork thingy * Fixed unit tests in checkpoint_test.go and conf_test.go * Removed unnecessary comments * improved conf code coverage by an amount that is greater than 0! * improved coverage, but line 144 of conf.go needs a look * Added unit tests to multus and types, also fixed a bug in conf.go * added label to import types/020 in types.go * hopefully resolved merge conflicts * increased code coverage in multus.go and conf.go, also added bug fixes and formatting * addressed all comments in review * Updated testing.go with better comments * changed 'thejohn' to '_not_type' for readability * added additional unit tests * added tests to kubeletclient.go * added more unit tests to k8sclient.go and kubeletclient.go * Added network status annotations section to quickstart and added more unit tests * made changes to tests based on code review
This commit is contained in:
@@ -176,6 +176,33 @@ You should note that there's 3 interfaces:
|
||||
* `eth0` our default network
|
||||
* `net1` the new interface we created with the macvlan configuration.
|
||||
|
||||
### Network Status Annotations
|
||||
|
||||
For additional confirmation, use `kubectl describe pod samplepod` and there will be an annotations section, similar to the following:
|
||||
|
||||
```
|
||||
Annotations: k8s.v1.cni.cncf.io/networks: macvlan-conf
|
||||
k8s.v1.cni.cncf.io/networks-status:
|
||||
[{
|
||||
"name": "cbr0",
|
||||
"ips": [
|
||||
"10.244.1.73"
|
||||
],
|
||||
"default": true,
|
||||
"dns": {}
|
||||
},{
|
||||
"name": "macvlan-conf",
|
||||
"interface": "net1",
|
||||
"ips": [
|
||||
"192.168.1.205"
|
||||
],
|
||||
"mac": "86:1d:96:ff:55:0d",
|
||||
"dns": {}
|
||||
}]
|
||||
```
|
||||
|
||||
This metadata tells us that we have two CNI plugins running successfully.
|
||||
|
||||
### What if I want more interfaces?
|
||||
|
||||
You can add more interfaces to a pod by creating more custom resources and then referring to them in pod's annotation. You can also reuse configurations, so for example, to attach two macvlan interfaces to a pod, you could create a pod like so:
|
||||
@@ -198,4 +225,4 @@ EOF
|
||||
|
||||
Note that the annotation now reads `k8s.v1.cni.cncf.io/networks: macvlan-conf,macvlan-conf`. Where we have the same configuration used twice, separated by a comma.
|
||||
|
||||
If you were to create another custom resource with the name `foo` you could use that such as: `k8s.v1.cni.cncf.io/networks: foo,macvlan-conf`, and use any number of attachments.
|
||||
If you were to create another custom resource with the name `foo` you could use that such as: `k8s.v1.cni.cncf.io/networks: foo,macvlan-conf`, and use any number of attachments.
|
@@ -22,6 +22,8 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
types020 "github.com/containernetworking/cni/pkg/types/020"
|
||||
testhelpers "github.com/intel/multus-cni/testing"
|
||||
testutils "github.com/intel/multus-cni/testing"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
@@ -611,4 +613,187 @@ var _ = Describe("k8sclient operations", func() {
|
||||
Expect(err).To(MatchError("GetPodNetwork: namespace isolation violation: podnamespace: test / target namespace: kube-system"))
|
||||
|
||||
})
|
||||
|
||||
It("Returns proper error message", func() {
|
||||
// getPodNetwork will give us the error, then this test will use that error on the top func boi
|
||||
err := &NoK8sNetworkError{"no kubernetes network found"}
|
||||
Expect(err.Error()).To(Equal("no kubernetes network found"))
|
||||
})
|
||||
|
||||
It("Sets pod network annotations without error", func() {
|
||||
fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")
|
||||
|
||||
net1 := `{
|
||||
"name": "net1",
|
||||
"type": "mynet",
|
||||
"cniVersion": "0.2.0"
|
||||
}`
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
|
||||
}
|
||||
|
||||
fKubeClient := testutils.NewFakeKubeClient()
|
||||
fKubeClient.AddPod(fakePod)
|
||||
fKubeClient.AddNetConfig("kube-system", "net1", net1)
|
||||
|
||||
kubeClient, err := GetK8sClient("", fKubeClient)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
k8sArgs, err := GetK8sArgs(args)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
pod, err := kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
networkstatus := "test status"
|
||||
_, err = setPodNetworkAnnotation(kubeClient, "test", pod, networkstatus)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
// Still figuring this one out. need to make "setPodNetworkAnnotation throw an error
|
||||
// It("Fails to set pod network annotations without error", func() {
|
||||
// fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")
|
||||
|
||||
// net1 := `{
|
||||
// "name": "net1",
|
||||
// "type": "mynet",
|
||||
// "cniVersion": "0.2.0"
|
||||
// }`
|
||||
|
||||
// args := &skel.CmdArgs{
|
||||
// Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
|
||||
// }
|
||||
|
||||
// fKubeClient := testutils.NewFakeKubeClient()
|
||||
// fKubeClient.AddPod(fakePod)
|
||||
// fKubeClient.AddNetConfig("kube-system", "net1", net1)
|
||||
|
||||
// kubeClient, err := GetK8sClient("", fKubeClient)
|
||||
// Expect(err).NotTo(HaveOccurred())
|
||||
// k8sArgs, err := GetK8sArgs(args)
|
||||
// Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// pod, err := kubeClient.GetPod(string(k8sArgs.K8S_POD_NAMESPACE), string(k8sArgs.K8S_POD_NAME))
|
||||
// Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// networkstatus := "test status"
|
||||
// _, err = setPodNetworkAnnotation(kubeClient, "test", pod, networkstatus)
|
||||
// Expect(err).NotTo(HaveOccurred())
|
||||
// })
|
||||
|
||||
It("Sets network status without error", func() {
|
||||
result := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.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 := types.LoadNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
|
||||
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
netstatus := []*types.NetworkStatus{delegateNetStatus}
|
||||
|
||||
fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")
|
||||
|
||||
netConf, err := types.LoadNetConf([]byte(conf))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
net1 := `{
|
||||
"name": "net1",
|
||||
"type": "mynet",
|
||||
"cniVersion": "0.2.0"
|
||||
}`
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
|
||||
}
|
||||
|
||||
fKubeClient := testutils.NewFakeKubeClient()
|
||||
fKubeClient.AddPod(fakePod)
|
||||
fKubeClient.AddNetConfig("kube-system", "net1", net1)
|
||||
|
||||
kubeClient, err := GetK8sClient("", fKubeClient)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
k8sArgs, err := GetK8sArgs(args)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = SetNetworkStatus(kubeClient, k8sArgs, netstatus, netConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Fails to set network status without error", func() {
|
||||
result := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.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, "")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
delegateNetStatus, err := types.LoadNetworkStatus(result, delegate.Conf.Name, delegate.MasterPlugin)
|
||||
GinkgoT().Logf("delegateNetStatus %+v\n", delegateNetStatus)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
netstatus := []*types.NetworkStatus{delegateNetStatus}
|
||||
|
||||
fakePod := testutils.NewFakePod("testpod", "kube-system/net1", "")
|
||||
|
||||
netConf, err := types.LoadNetConf([]byte(conf))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
net1 := `{
|
||||
"name": "net1",
|
||||
"type": "mynet",
|
||||
"cniVersion": "0.2.0"
|
||||
}`
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
|
||||
}
|
||||
|
||||
fKubeClient := testutils.NewFakeKubeClient()
|
||||
fKubeClient.AddPod(fakePod)
|
||||
fKubeClient.AddNetConfig("kube-system", "net1", net1)
|
||||
|
||||
k8sArgs, err := GetK8sArgs(args)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = SetNetworkStatus(nil, k8sArgs, netstatus, netConf)
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
@@ -115,6 +115,12 @@ var _ = Describe("Kubelet resource endpoint data read operations", func() {
|
||||
_, err := GetResourceClient()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should fail with missing file", func() {
|
||||
kubeletSocket = "sampleSocketString"
|
||||
_, err := GetResourceClient()
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("GetPodResourceMap() with valid pod name and namespace", func() {
|
||||
@@ -146,6 +152,41 @@ var _ = Describe("Kubelet resource endpoint data read operations", func() {
|
||||
Expect(resourceMap).ShouldNot(BeNil())
|
||||
Expect(resourceMap).To(Equal(outputRMap))
|
||||
})
|
||||
|
||||
It("should return no error with empty socket", func() {
|
||||
podUID := k8sTypes.UID("970a395d-bb3b-11e8-89df-408d5c537d23")
|
||||
fakePod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-name",
|
||||
Namespace: "pod-namespace",
|
||||
UID: podUID,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "container-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
kubeletSocket = ""
|
||||
client, err := getKubeletClient()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
outputRMap := map[string]*mtypes.ResourceInfo{
|
||||
"resource": &mtypes.ResourceInfo{DeviceIDs: []string{"dev0", "dev1"}},
|
||||
}
|
||||
resourceMap, err := client.GetPodResourceMap(fakePod)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(resourceMap).ShouldNot(BeNil())
|
||||
Expect(resourceMap).To(Equal(outputRMap))
|
||||
})
|
||||
|
||||
It("should return an error with garbage socket value", func() {
|
||||
kubeletSocket = "/badfilepath!?//"
|
||||
_, err := getKubeletClient()
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("GetPodResourceMap() with empty podname", func() {
|
||||
|
@@ -45,6 +45,12 @@ var _ = Describe("logging operations", func() {
|
||||
// check file existance
|
||||
})
|
||||
|
||||
It("Check file setter with bad filepath", func() {
|
||||
SetLogFile("/invalid/filepath")
|
||||
Expect(loggingFp).NotTo(Equal(nil))
|
||||
// check file existance
|
||||
})
|
||||
|
||||
It("Check loglevel setter", func() {
|
||||
SetLogLevel("debug")
|
||||
Expect(loggingLevel).To(Equal(DebugLevel))
|
||||
|
@@ -32,9 +32,10 @@ import (
|
||||
cniversion "github.com/containernetworking/cni/pkg/version"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
|
||||
"github.com/intel/multus-cni/k8sclient"
|
||||
"github.com/intel/multus-cni/logging"
|
||||
testhelpers "github.com/intel/multus-cni/testing"
|
||||
"github.com/intel/multus-cni/types"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@@ -324,6 +325,162 @@ var _ = Describe("multus operations", func() {
|
||||
}
|
||||
})
|
||||
|
||||
It("returns the previous result using cmdGet", 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"
|
||||
}]
|
||||
}`),
|
||||
}
|
||||
|
||||
logging.SetLogLevel("verbose")
|
||||
|
||||
// Touch the default network file.
|
||||
configPath := "/tmp/foo.multus.conf"
|
||||
os.OpenFile(configPath, os.O_RDONLY|os.O_CREATE, 0755)
|
||||
|
||||
fExec := &fakeExec{}
|
||||
expectedResult1 := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.2/24"),
|
||||
},
|
||||
}
|
||||
expectedConf1 := `{
|
||||
"name": "weave1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "weave-net"
|
||||
}`
|
||||
fExec.addPlugin(nil, "eth0", expectedConf1, expectedResult1, nil)
|
||||
|
||||
expectedResult2 := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.5/24"),
|
||||
},
|
||||
}
|
||||
expectedConf2 := `{
|
||||
"name": "other1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "other-plugin"
|
||||
}`
|
||||
fExec.addPlugin(nil, "net1", expectedConf2, expectedResult2, nil)
|
||||
|
||||
os.Setenv("CNI_COMMAND", "ADD")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
result, err := cmdAdd(args, fExec, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fExec.addIndex).To(Equal(len(fExec.plugins)))
|
||||
r := result.(*types020.Result)
|
||||
// plugin 1 is the masterplugin
|
||||
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
||||
|
||||
result, err = cmdGet(args, fExec, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
os.Setenv("CNI_COMMAND", "DEL")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
err = cmdDel(args, fExec, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fExec.delIndex).To(Equal(len(fExec.plugins)))
|
||||
|
||||
// Cleanup default network file.
|
||||
if _, errStat := os.Stat(configPath); errStat == nil {
|
||||
errRemove := os.Remove(configPath)
|
||||
Expect(errRemove).NotTo(HaveOccurred())
|
||||
}
|
||||
})
|
||||
|
||||
It("executes delegates given faulty namespace", func() {
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "123456789",
|
||||
Netns: "fsdadfad",
|
||||
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"
|
||||
}]
|
||||
}`),
|
||||
}
|
||||
// Netns is given garbage value
|
||||
|
||||
// Touch the default network file.
|
||||
configPath := "/tmp/foo.multus.conf"
|
||||
os.OpenFile(configPath, os.O_RDONLY|os.O_CREATE, 0755)
|
||||
|
||||
fExec := &fakeExec{}
|
||||
expectedResult1 := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.2/24"),
|
||||
},
|
||||
}
|
||||
expectedConf1 := `{
|
||||
"name": "weave1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "weave-net"
|
||||
}`
|
||||
fExec.addPlugin(nil, "eth0", expectedConf1, expectedResult1, nil)
|
||||
|
||||
expectedResult2 := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.5/24"),
|
||||
},
|
||||
}
|
||||
expectedConf2 := `{
|
||||
"name": "other1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "other-plugin"
|
||||
}`
|
||||
fExec.addPlugin(nil, "net1", expectedConf2, expectedResult2, nil)
|
||||
|
||||
os.Setenv("CNI_COMMAND", "ADD")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
result, err := cmdAdd(args, fExec, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fExec.addIndex).To(Equal(len(fExec.plugins)))
|
||||
r := result.(*types020.Result)
|
||||
// plugin 1 is the masterplugin
|
||||
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
||||
|
||||
os.Setenv("CNI_COMMAND", "DEL")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
err = cmdDel(args, fExec, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fExec.delIndex).To(Equal(len(fExec.plugins)))
|
||||
|
||||
// Cleanup default network file.
|
||||
if _, errStat := os.Stat(configPath); errStat == nil {
|
||||
errRemove := os.Remove(configPath)
|
||||
Expect(errRemove).NotTo(HaveOccurred())
|
||||
}
|
||||
})
|
||||
|
||||
It("returns the previous result using cmdGet", func() {
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "123456789",
|
||||
@@ -893,6 +1050,74 @@ var _ = Describe("multus operations", func() {
|
||||
Expect(fExec.delIndex).To(Equal(len(fExec.plugins)))
|
||||
})
|
||||
|
||||
It("executes kubernetes networks and delete it after pod removal", func() {
|
||||
fakePod := testhelpers.NewFakePod("testpod", "net1", "")
|
||||
net1 := `{
|
||||
"name": "net1",
|
||||
"type": "mynet",
|
||||
"cniVersion": "0.2.0"
|
||||
}`
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "123456789",
|
||||
Netns: testNS.Path(),
|
||||
IfName: "eth0",
|
||||
Args: fmt.Sprintf("K8S_POD_NAME=%s;K8S_POD_NAMESPACE=%s", fakePod.ObjectMeta.Name, fakePod.ObjectMeta.Namespace),
|
||||
StdinData: []byte(`{
|
||||
"name": "node-cni-network",
|
||||
"type": "multus",
|
||||
"kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml",
|
||||
"delegates": [{
|
||||
"name": "weave1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "weave-net"
|
||||
}]
|
||||
}`),
|
||||
}
|
||||
|
||||
fExec := &fakeExec{}
|
||||
expectedResult1 := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.2/24"),
|
||||
},
|
||||
}
|
||||
expectedConf1 := `{
|
||||
"name": "weave1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "weave-net"
|
||||
}`
|
||||
fExec.addPlugin(nil, "eth0", expectedConf1, expectedResult1, nil)
|
||||
fExec.addPlugin(nil, "net1", net1, &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.3/24"),
|
||||
},
|
||||
}, nil)
|
||||
|
||||
fKubeClient := testhelpers.NewFakeKubeClient()
|
||||
fKubeClient.AddPod(fakePod)
|
||||
fKubeClient.AddNetConfig(fakePod.ObjectMeta.Namespace, "net1", net1)
|
||||
|
||||
os.Setenv("CNI_COMMAND", "ADD")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
result, err := cmdAdd(args, fExec, fKubeClient)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fExec.addIndex).To(Equal(len(fExec.plugins)))
|
||||
Expect(fKubeClient.PodCount).To(Equal(2))
|
||||
Expect(fKubeClient.NetCount).To(Equal(1))
|
||||
r := result.(*types020.Result)
|
||||
// plugin 1 is the masterplugin
|
||||
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
||||
|
||||
os.Setenv("CNI_COMMAND", "DEL")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
// set fKubeClient to nil to emulate no pod info
|
||||
fKubeClient.DeletePod(fakePod)
|
||||
err = cmdDel(args, fExec, fKubeClient)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(fExec.delIndex).To(Equal(len(fExec.plugins)))
|
||||
})
|
||||
|
||||
It("ensure delegates get portmap runtime config", func() {
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "123456789",
|
||||
@@ -1148,4 +1373,121 @@ var _ = Describe("multus operations", func() {
|
||||
Expect(fKubeClient.PodCount).To(Equal(4))
|
||||
Expect(fKubeClient.NetCount).To(Equal(2))
|
||||
})
|
||||
|
||||
It("fails to execute confListDel given no 'plugins' key", 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"
|
||||
}]
|
||||
}`),
|
||||
}
|
||||
|
||||
// Touch the default network file.
|
||||
configPath := "/tmp/foo.multus.conf"
|
||||
os.OpenFile(configPath, os.O_RDONLY|os.O_CREATE, 0755)
|
||||
|
||||
fExec := &fakeExec{}
|
||||
expectedResult1 := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.2/24"),
|
||||
},
|
||||
}
|
||||
expectedConf1 := `{
|
||||
"name": "weave1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "weave-net"
|
||||
}`
|
||||
fExec.addPlugin(nil, "eth0", expectedConf1, expectedResult1, nil)
|
||||
|
||||
expectedResult2 := &types020.Result{
|
||||
CNIVersion: "0.2.0",
|
||||
IP4: &types020.IPConfig{
|
||||
IP: *testhelpers.EnsureCIDR("1.1.1.5/24"),
|
||||
},
|
||||
}
|
||||
expectedConf2 := `{
|
||||
"name": "other1",
|
||||
"cniVersion": "0.2.0",
|
||||
"type": "other-plugin"
|
||||
}`
|
||||
fExec.addPlugin(nil, "net1", expectedConf2, expectedResult2, nil)
|
||||
|
||||
os.Setenv("CNI_COMMAND", "ADD")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
|
||||
binDir := "/opt/cni/bin"
|
||||
// use fExec for the exec param
|
||||
rawnetconflist := []byte(`{"cniVersion":"0.2.0","name":"weave1","type":"weave-net"}`)
|
||||
k8sargs, err := k8sclient.GetK8sArgs(args)
|
||||
n, err := types.LoadNetConf(args.StdinData)
|
||||
rt := types.CreateCNIRuntimeConf(args, k8sargs, args.IfName, n.RuntimeConfig)
|
||||
|
||||
err = conflistDel(rt, rawnetconflist, binDir, fExec)
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("executes confListDel without error", func() {
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "123456789",
|
||||
Netns: testNS.Path(),
|
||||
IfName: "eth0",
|
||||
StdinData: []byte(`{
|
||||
"name": "node-cni-network",
|
||||
"type": "multus",
|
||||
"delegates": [{
|
||||
"cniVersion": "0.3.1",
|
||||
"name": "mynet-confList",
|
||||
"plugins": [
|
||||
{
|
||||
"type": "firstPlugin",
|
||||
"capabilities": {"portMappings": true}
|
||||
}
|
||||
]
|
||||
}],
|
||||
"runtimeConfig": {
|
||||
"portMappings": [
|
||||
{"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
|
||||
]
|
||||
}
|
||||
}`),
|
||||
}
|
||||
|
||||
// Touch the default network file.
|
||||
configPath := "/tmp/foo.multus.conf"
|
||||
os.OpenFile(configPath, os.O_RDONLY|os.O_CREATE, 0755)
|
||||
|
||||
fExec := &fakeExec{}
|
||||
expectedConf1 := `{
|
||||
"capabilities": {"portMappings": true},
|
||||
"name": "mynet-confList",
|
||||
"cniVersion": "0.3.1",
|
||||
"type": "firstPlugin",
|
||||
"runtimeConfig": {
|
||||
"portMappings": [
|
||||
{"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
|
||||
]
|
||||
}
|
||||
}`
|
||||
fExec.addPlugin(nil, "eth0", expectedConf1, nil, nil)
|
||||
os.Setenv("CNI_COMMAND", "ADD")
|
||||
os.Setenv("CNI_IFNAME", "eth0")
|
||||
|
||||
err := cmdDel(args, fExec, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
@@ -468,4 +468,48 @@ var _ = Describe("config operations", func() {
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("using UnmarshalJSON", func() {
|
||||
It("succeeds with valid json", func() {
|
||||
networkselectionelement := &NetworkSelectionElement{
|
||||
Name: "kube-system",
|
||||
Namespace: "net1",
|
||||
InterfaceRequest: "",
|
||||
}
|
||||
conf := `{
|
||||
"name": "kube-system",
|
||||
"namespace": "net1",
|
||||
"interfaceRequest": "",
|
||||
"ips": "10.18.89.129",
|
||||
"mac": "CB-32-97-FF-D6-79",
|
||||
"interface": ""
|
||||
}`
|
||||
err := networkselectionelement.UnmarshalJSON([]byte(conf))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("fails to parse invalid json", func() {
|
||||
networkselectionelement := &NetworkSelectionElement{
|
||||
Name: "kube-system",
|
||||
Namespace: "net1",
|
||||
InterfaceRequest: "",
|
||||
}
|
||||
err := networkselectionelement.UnmarshalJSON([]byte("invalidjson~"))
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("fails with missing name parameter", func() {
|
||||
networkselectionelement := &NetworkSelectionElement{
|
||||
Name: "kube-system",
|
||||
Namespace: "net1",
|
||||
InterfaceRequest: "",
|
||||
}
|
||||
// conf json does not include "name"
|
||||
conf := `{
|
||||
"namespace": "net1",
|
||||
"interfaceRequest": ""
|
||||
}`
|
||||
err := networkselectionelement.UnmarshalJSON([]byte(conf))
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user