forked from github/multus-cni
This changes introduce goreleaser, which does cross-compile and package, as well as add version into go code. This change also changes .travis.yml to allow to other users' forked repo.
786 lines
22 KiB
Go
786 lines
22 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/containernetworking/cni/pkg/skel"
|
|
cnitypes "github.com/containernetworking/cni/pkg/types"
|
|
"github.com/containernetworking/cni/pkg/types/020"
|
|
cniversion "github.com/containernetworking/cni/pkg/version"
|
|
"github.com/containernetworking/plugins/pkg/ns"
|
|
"github.com/containernetworking/plugins/pkg/testutils"
|
|
|
|
testhelpers "github.com/intel/multus-cni/testing"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
func TestMultus(t *testing.T) {
|
|
RegisterFailHandler(Fail)
|
|
RunSpecs(t, "multus")
|
|
}
|
|
|
|
type fakePlugin struct {
|
|
expectedEnv []string
|
|
expectedConf string
|
|
expectedIfname string
|
|
result cnitypes.Result
|
|
err error
|
|
}
|
|
|
|
type fakeExec struct {
|
|
cniversion.PluginDecoder
|
|
|
|
addIndex int
|
|
delIndex int
|
|
plugins []*fakePlugin
|
|
}
|
|
|
|
func (f *fakeExec) addPlugin(expectedEnv []string, expectedIfname, expectedConf string, result *types020.Result, err error) {
|
|
f.plugins = append(f.plugins, &fakePlugin{
|
|
expectedEnv: expectedEnv,
|
|
expectedConf: expectedConf,
|
|
expectedIfname: expectedIfname,
|
|
result: result,
|
|
err: err,
|
|
})
|
|
}
|
|
|
|
func matchArray(a1, a2 []string) {
|
|
Expect(len(a1)).To(Equal(len(a2)))
|
|
for _, e1 := range a1 {
|
|
found := ""
|
|
for _, e2 := range a2 {
|
|
if e1 == e2 {
|
|
found = e2
|
|
break
|
|
}
|
|
}
|
|
// Compare element values for more descriptive test failure
|
|
Expect(e1).To(Equal(found))
|
|
}
|
|
}
|
|
|
|
// When faking plugin execution the ExecPlugin() call environ is not populated
|
|
// (while it would be for real exec). Filter the environment variables for
|
|
// CNI-specific ones that testcases will care about.
|
|
func gatherCNIEnv() []string {
|
|
filtered := make([]string, 0)
|
|
for _, env := range os.Environ() {
|
|
if strings.HasPrefix(env, "CNI_") {
|
|
filtered = append(filtered, env)
|
|
}
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
func (f *fakeExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
|
|
cmd := os.Getenv("CNI_COMMAND")
|
|
var index int
|
|
switch cmd {
|
|
case "ADD":
|
|
Expect(len(f.plugins)).To(BeNumerically(">", f.addIndex))
|
|
index = f.addIndex
|
|
f.addIndex++
|
|
case "DEL":
|
|
Expect(len(f.plugins)).To(BeNumerically(">", f.delIndex))
|
|
index = len(f.plugins) - f.delIndex - 1
|
|
f.delIndex++
|
|
default:
|
|
// Should never be reached
|
|
Expect(false).To(BeTrue())
|
|
}
|
|
plugin := f.plugins[index]
|
|
|
|
GinkgoT().Logf("[%s %d] exec plugin %q found %+v\n", cmd, index, pluginPath, plugin)
|
|
|
|
if plugin.expectedConf != "" {
|
|
Expect(string(stdinData)).To(MatchJSON(plugin.expectedConf))
|
|
}
|
|
if plugin.expectedIfname != "" {
|
|
Expect(os.Getenv("CNI_IFNAME")).To(Equal(plugin.expectedIfname))
|
|
}
|
|
|
|
if len(plugin.expectedEnv) > 0 {
|
|
cniEnv := gatherCNIEnv()
|
|
for _, expectedCniEnvVar := range plugin.expectedEnv {
|
|
Expect(cniEnv).Should(ContainElement(expectedCniEnvVar))
|
|
}
|
|
}
|
|
|
|
if plugin.err != nil {
|
|
return nil, plugin.err
|
|
}
|
|
|
|
resultJSON, err := json.Marshal(plugin.result)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
return resultJSON, nil
|
|
}
|
|
|
|
func (f *fakeExec) FindInPath(plugin string, paths []string) (string, error) {
|
|
Expect(len(paths)).To(BeNumerically(">", 0))
|
|
return filepath.Join(paths[0], plugin), nil
|
|
}
|
|
|
|
var _ = Describe("multus operations", func() {
|
|
var testNS ns.NetNS
|
|
var tmpDir string
|
|
|
|
BeforeEach(func() {
|
|
// Create a new NetNS so we don't modify the host
|
|
var err error
|
|
testNS, err = testutils.NewNS()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
os.Setenv("CNI_NETNS", testNS.Path())
|
|
os.Setenv("CNI_PATH", "/some/path")
|
|
|
|
tmpDir, err = ioutil.TempDir("", "multus_tmp")
|
|
Expect(err).NotTo(HaveOccurred())
|
|
})
|
|
|
|
AfterEach(func() {
|
|
Expect(testNS.Close()).To(Succeed())
|
|
os.Unsetenv("CNI_PATH")
|
|
os.Unsetenv("CNI_ARGS")
|
|
err := os.RemoveAll(tmpDir)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
})
|
|
|
|
It("executes delegates", 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")
|
|
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("executes delegates and cleans up on failure", func() {
|
|
expectedConf1 := `{
|
|
"name": "weave1",
|
|
"cniVersion": "0.2.0",
|
|
"type": "weave-net"
|
|
}`
|
|
expectedConf2 := `{
|
|
"name": "other1",
|
|
"cniVersion": "0.2.0",
|
|
"type": "other-plugin"
|
|
}`
|
|
args := &skel.CmdArgs{
|
|
ContainerID: "123456789",
|
|
Netns: testNS.Path(),
|
|
IfName: "eth0",
|
|
StdinData: []byte(fmt.Sprintf(`{
|
|
"name": "node-cni-network",
|
|
"type": "multus",
|
|
"defaultnetworkfile": "/tmp/foo.multus.conf",
|
|
"defaultnetworkwaitseconds": 3,
|
|
"delegates": [%s,%s]
|
|
}`, expectedConf1, expectedConf2)),
|
|
}
|
|
|
|
// 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"),
|
|
},
|
|
}
|
|
fExec.addPlugin(nil, "eth0", expectedConf1, expectedResult1, nil)
|
|
|
|
// This plugin invocation should fail
|
|
err := fmt.Errorf("expected plugin failure")
|
|
fExec.addPlugin(nil, "net1", expectedConf2, nil, err)
|
|
|
|
os.Setenv("CNI_COMMAND", "ADD")
|
|
os.Setenv("CNI_IFNAME", "eth0")
|
|
_, err = cmdAdd(args, fExec, nil)
|
|
Expect(fExec.addIndex).To(Equal(2))
|
|
Expect(fExec.delIndex).To(Equal(2))
|
|
Expect(err).To(MatchError("Multus: Err adding pod to network \"other1\": Multus: error in invoke Delegate add - \"other-plugin\": expected plugin failure"))
|
|
|
|
// Cleanup default network file.
|
|
if _, errStat := os.Stat(configPath); errStat == nil {
|
|
errRemove := os.Remove(configPath)
|
|
Expect(errRemove).NotTo(HaveOccurred())
|
|
}
|
|
|
|
})
|
|
|
|
It("executes delegates with interface name and MAC and IP addr", func() {
|
|
podNet := `[{"name":"net1",
|
|
"interface": "test1",
|
|
"ips":"1.2.3.4/24"},
|
|
{"name":"net2",
|
|
"mac": "c2:11:22:33:44:66",
|
|
"ips": "10.0.0.1"}
|
|
]`
|
|
fakePod := testhelpers.NewFakePod("testpod", podNet, "")
|
|
net1 := `{
|
|
"name": "net1",
|
|
"type": "mynet",
|
|
"cniVersion": "0.2.0"
|
|
}`
|
|
net2 := `{
|
|
"name": "net2",
|
|
"type": "mynet2",
|
|
"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([]string{"CNI_ARGS=IgnoreUnknown=true;IP=1.2.3.4/24"}, "test1", net1, &types020.Result{
|
|
CNIVersion: "0.2.0",
|
|
IP4: &types020.IPConfig{
|
|
IP: *testhelpers.EnsureCIDR("1.1.1.3/24"),
|
|
},
|
|
}, nil)
|
|
fExec.addPlugin([]string{"CNI_ARGS=IgnoreUnknown=true;MAC=c2:11:22:33:44:66;IP=10.0.0.1"}, "net2", net2, &types020.Result{
|
|
CNIVersion: "0.2.0",
|
|
IP4: &types020.IPConfig{
|
|
IP: *testhelpers.EnsureCIDR("1.1.1.4/24"),
|
|
},
|
|
}, nil)
|
|
|
|
fKubeClient := testhelpers.NewFakeKubeClient()
|
|
fKubeClient.AddPod(fakePod)
|
|
fKubeClient.AddNetConfig(fakePod.ObjectMeta.Namespace, "net1", net1)
|
|
fKubeClient.AddNetConfig(fakePod.ObjectMeta.Namespace, "net2", net2)
|
|
|
|
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(2))
|
|
r := result.(*types020.Result)
|
|
// plugin 1 is the masterplugin
|
|
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
|
})
|
|
|
|
It("executes delegates and kubernetes networks", func() {
|
|
fakePod := testhelpers.NewFakePod("testpod", "net1,net2", "")
|
|
net1 := `{
|
|
"name": "net1",
|
|
"type": "mynet",
|
|
"cniVersion": "0.2.0"
|
|
}`
|
|
net2 := `{
|
|
"name": "net2",
|
|
"type": "mynet2",
|
|
"cniVersion": "0.2.0"
|
|
}`
|
|
net3 := `{
|
|
"name": "net3",
|
|
"type": "mynet3",
|
|
"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)
|
|
fExec.addPlugin(nil, "net2", net2, &types020.Result{
|
|
CNIVersion: "0.2.0",
|
|
IP4: &types020.IPConfig{
|
|
IP: *testhelpers.EnsureCIDR("1.1.1.4/24"),
|
|
},
|
|
}, nil)
|
|
|
|
fKubeClient := testhelpers.NewFakeKubeClient()
|
|
fKubeClient.AddPod(fakePod)
|
|
fKubeClient.AddNetConfig(fakePod.ObjectMeta.Namespace, "net1", net1)
|
|
fKubeClient.AddNetConfig(fakePod.ObjectMeta.Namespace, "net2", net2)
|
|
// net3 is not used; make sure it's not accessed
|
|
fKubeClient.AddNetConfig(fakePod.ObjectMeta.Namespace, "net3", net3)
|
|
|
|
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(2))
|
|
r := result.(*types020.Result)
|
|
// plugin 1 is the masterplugin
|
|
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
|
})
|
|
|
|
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",
|
|
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"}
|
|
]
|
|
}
|
|
}`),
|
|
}
|
|
|
|
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 := cmdAdd(args, fExec, nil)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
})
|
|
|
|
It("executes clusterNetwork delegate", func() {
|
|
fakePod := testhelpers.NewFakePod("testpod", "", "kube-system/net1")
|
|
net1 := `{
|
|
"name": "net1",
|
|
"type": "mynet",
|
|
"cniVersion": "0.2.0"
|
|
}`
|
|
expectedResult1 := &types020.Result{
|
|
CNIVersion: "0.2.0",
|
|
IP4: &types020.IPConfig{
|
|
IP: *testhelpers.EnsureCIDR("1.1.1.2/24"),
|
|
},
|
|
}
|
|
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",
|
|
"defaultNetworks": [],
|
|
"clusterNetwork": "net1",
|
|
"delegates": []
|
|
}`),
|
|
}
|
|
|
|
fExec := &fakeExec{}
|
|
fExec.addPlugin(nil, "eth0", net1, expectedResult1, nil)
|
|
|
|
fKubeClient := testhelpers.NewFakeKubeClient()
|
|
fKubeClient.AddPod(fakePod)
|
|
fKubeClient.AddNetConfig("kube-system", "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(2))
|
|
r := result.(*types020.Result)
|
|
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
|
|
|
os.Setenv("CNI_COMMAND", "DEL")
|
|
os.Setenv("CNI_IFNAME", "eth0")
|
|
err = cmdDel(args, fExec, fKubeClient)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(fExec.delIndex).To(Equal(len(fExec.plugins)))
|
|
})
|
|
|
|
It("Verify the cache is created in dataDir", func() {
|
|
tmpCNIDir := tmpDir + "/cniData"
|
|
err := os.Mkdir(tmpCNIDir, 0777)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
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(fmt.Sprintf(`{
|
|
"name": "node-cni-network",
|
|
"type": "multus",
|
|
"kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml",
|
|
"cniDir": "%s",
|
|
"delegates": [{
|
|
"name": "weave1",
|
|
"cniVersion": "0.2.0",
|
|
"type": "weave-net"
|
|
}]
|
|
}`, tmpCNIDir)),
|
|
}
|
|
|
|
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())
|
|
|
|
By("Verify cache file existence")
|
|
cacheFilePath := fmt.Sprintf("%s/%s", tmpCNIDir, "123456789")
|
|
_, err = os.Stat(cacheFilePath)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
By("Delete and check net count is not incremented")
|
|
os.Setenv("CNI_COMMAND", "DEL")
|
|
os.Setenv("CNI_IFNAME", "eth0")
|
|
err = cmdDel(args, fExec, fKubeClient)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(fExec.delIndex).To(Equal(len(fExec.plugins)))
|
|
Expect(fKubeClient.PodCount).To(Equal(3))
|
|
Expect(fKubeClient.NetCount).To(Equal(1))
|
|
})
|
|
|
|
It("Delete pod without cache", func() {
|
|
tmpCNIDir := tmpDir + "/cniData"
|
|
err := os.Mkdir(tmpCNIDir, 0777)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
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(fmt.Sprintf(`{
|
|
"name": "node-cni-network",
|
|
"type": "multus",
|
|
"kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml",
|
|
"cniDir": "%s",
|
|
"delegates": [{
|
|
"name": "weave1",
|
|
"cniVersion": "0.2.0",
|
|
"type": "weave-net"
|
|
}]
|
|
}`, tmpCNIDir)),
|
|
}
|
|
|
|
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())
|
|
|
|
By("Verify cache file existence")
|
|
cacheFilePath := fmt.Sprintf("%s/%s", tmpCNIDir, "123456789")
|
|
_, err = os.Stat(cacheFilePath)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
err = os.Remove(cacheFilePath)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
By("Delete and check pod/net count is incremented")
|
|
os.Setenv("CNI_COMMAND", "DEL")
|
|
os.Setenv("CNI_IFNAME", "eth0")
|
|
err = cmdDel(args, fExec, fKubeClient)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(fExec.delIndex).To(Equal(len(fExec.plugins)))
|
|
Expect(fKubeClient.PodCount).To(Equal(4))
|
|
Expect(fKubeClient.NetCount).To(Equal(2))
|
|
})
|
|
})
|