vendor: bump CNI to 1a9288c3c09cea4e580fdb1a636f1c5e185a391f
authorDan Williams <dcbw@redhat.com>
Wed, 10 May 2017 03:36:26 +0000 (22:36 -0500)
committerDan Williams <dcbw@redhat.com>
Wed, 10 May 2017 03:45:44 +0000 (22:45 -0500)
12 files changed:
Godeps/Godeps.json
vendor/github.com/containernetworking/cni/pkg/invoke/exec_test.go
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec_test.go
vendor/github.com/containernetworking/cni/pkg/ip/link.go
vendor/github.com/containernetworking/cni/pkg/ip/link_test.go
vendor/github.com/containernetworking/cni/pkg/types/020/types.go
vendor/github.com/containernetworking/cni/pkg/types/current/types.go
vendor/github.com/containernetworking/cni/pkg/utils/sysctl/sysctl_linux.go [new file with mode: 0644]
vendor/github.com/containernetworking/cni/pkg/utils/utils.go [new file with mode: 0644]
vendor/github.com/containernetworking/cni/pkg/utils/utils_suite_test.go [new file with mode: 0644]
vendor/github.com/containernetworking/cni/pkg/utils/utils_test.go [new file with mode: 0644]
vendor/github.com/containernetworking/cni/pkg/version/version.go

index c0caa00..a284553 100644 (file)
@@ -9,57 +9,67 @@
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/invoke",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/ip",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/ipam",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/ns",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/skel",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/testutils",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/types",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/types/020",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/types/current",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
+               },
+               {
+                       "ImportPath": "github.com/containernetworking/cni/pkg/utils",
+                       "Comment": "v0.5.0",
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/utils/hwaddr",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
+               },
+               {
+                       "ImportPath": "github.com/containernetworking/cni/pkg/utils/sysctl",
+                       "Comment": "v0.5.0",
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/containernetworking/cni/pkg/version",
                        "Comment": "v0.5.0",
-                       "Rev": "4ce9b019aab51b28a32ff6549784a69f9b209fe4"
+                       "Rev": "1a9288c3c09cea4e580fdb1a636f1c5e185a391f"
                },
                {
                        "ImportPath": "github.com/coreos/go-iptables/iptables",
index 7e804ab..33ffc2d 100644 (file)
@@ -50,7 +50,7 @@ var _ = Describe("Executing a plugin, unit tests", func() {
                        VersionDecoder: versionDecoder,
                }
                pluginPath = "/some/plugin/path"
-               netconf = []byte(`{ "some": "stdin", "cniVersion": "0.3.0" }`)
+               netconf = []byte(`{ "some": "stdin", "cniVersion": "0.3.1" }`)
                cniargs = &fakes.CNIArgs{}
                cniargs.AsEnvCall.Returns.Env = []string{"SOME=ENV"}
        })
index 5ab23ae..5d759f2 100644 (file)
@@ -58,7 +58,7 @@ var _ = Describe("RawExec", func() {
                        "CNI_PATH=/some/bin/path",
                        "CNI_IFNAME=some-eth0",
                }
-               stdin = []byte(`{"some":"stdin-json", "cniVersion": "0.3.0"}`)
+               stdin = []byte(`{"some":"stdin-json", "cniVersion": "0.3.1"}`)
                execer = &invoke.RawExec{}
        })
 
index 6431bb4..a984262 100644 (file)
@@ -16,6 +16,7 @@ package ip
 
 import (
        "crypto/rand"
+       "errors"
        "fmt"
        "net"
        "os"
@@ -25,6 +26,10 @@ import (
        "github.com/vishvananda/netlink"
 )
 
+var (
+       ErrLinkNotFound = errors.New("link not found")
+)
+
 func makeVethPair(name, peer string, mtu int) (netlink.Link, error) {
        veth := &netlink.Veth{
                LinkAttrs: netlink.LinkAttrs{
@@ -98,30 +103,38 @@ func RenameLink(curName, newName string) error {
        return err
 }
 
-// SetupVeth sets up a virtual ethernet link.
-// Should be in container netns, and will switch back to hostNS to set the host
-// veth end up.
-func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (hostVeth, contVeth netlink.Link, err error) {
-       var hostVethName string
-       hostVethName, contVeth, err = makeVeth(contVethName, mtu)
+func ifaceFromNetlinkLink(l netlink.Link) net.Interface {
+       a := l.Attrs()
+       return net.Interface{
+               Index:        a.Index,
+               MTU:          a.MTU,
+               Name:         a.Name,
+               HardwareAddr: a.HardwareAddr,
+               Flags:        a.Flags,
+       }
+}
+
+// SetupVeth sets up a pair of virtual ethernet devices.
+// Call SetupVeth from inside the container netns.  It will create both veth
+// devices and move the host-side veth into the provided hostNS namespace.
+// On success, SetupVeth returns (hostVeth, containerVeth, nil)
+func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (net.Interface, net.Interface, error) {
+       hostVethName, contVeth, err := makeVeth(contVethName, mtu)
        if err != nil {
-               return
+               return net.Interface{}, net.Interface{}, err
        }
 
        if err = netlink.LinkSetUp(contVeth); err != nil {
-               err = fmt.Errorf("failed to set %q up: %v", contVethName, err)
-               return
+               return net.Interface{}, net.Interface{}, fmt.Errorf("failed to set %q up: %v", contVethName, err)
        }
 
-       hostVeth, err = netlink.LinkByName(hostVethName)
+       hostVeth, err := netlink.LinkByName(hostVethName)
        if err != nil {
-               err = fmt.Errorf("failed to lookup %q: %v", hostVethName, err)
-               return
+               return net.Interface{}, net.Interface{}, fmt.Errorf("failed to lookup %q: %v", hostVethName, err)
        }
 
        if err = netlink.LinkSetNsFd(hostVeth, int(hostNS.Fd())); err != nil {
-               err = fmt.Errorf("failed to move veth to host netns: %v", err)
-               return
+               return net.Interface{}, net.Interface{}, fmt.Errorf("failed to move veth to host netns: %v", err)
        }
 
        err = hostNS.Do(func(_ ns.NetNS) error {
@@ -135,7 +148,10 @@ func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (hostVeth, contVet
                }
                return nil
        })
-       return
+       if err != nil {
+               return net.Interface{}, net.Interface{}, err
+       }
+       return ifaceFromNetlinkLink(hostVeth), ifaceFromNetlinkLink(contVeth), nil
 }
 
 // DelLinkByName removes an interface link.
@@ -157,6 +173,9 @@ func DelLinkByName(ifName string) error {
 func DelLinkByNameAddr(ifName string, family int) (*net.IPNet, error) {
        iface, err := netlink.LinkByName(ifName)
        if err != nil {
+               if err != nil && err.Error() == "Link not found" {
+                       return nil, ErrLinkNotFound
+               }
                return nil, fmt.Errorf("failed to lookup %q: %v", ifName, err)
        }
 
index 3df9ab8..23182a5 100644 (file)
@@ -46,8 +46,8 @@ var _ = Describe("Link", func() {
                hostNetNS         ns.NetNS
                containerNetNS    ns.NetNS
                ifaceCounter      int = 0
-               hostVeth          netlink.Link
-               containerVeth     netlink.Link
+               hostVeth          net.Interface
+               containerVeth     net.Interface
                hostVethName      string
                containerVethName string
 
@@ -78,8 +78,8 @@ var _ = Describe("Link", func() {
                        }
                        Expect(err).NotTo(HaveOccurred())
 
-                       hostVethName = hostVeth.Attrs().Name
-                       containerVethName = containerVeth.Attrs().Name
+                       hostVethName = hostVeth.Name
+                       containerVethName = containerVeth.Name
 
                        return nil
                })
@@ -98,7 +98,7 @@ var _ = Describe("Link", func() {
 
                        containerVethFromName, err := netlink.LinkByName(containerVethName)
                        Expect(err).NotTo(HaveOccurred())
-                       Expect(containerVethFromName.Attrs().Index).To(Equal(containerVeth.Attrs().Index))
+                       Expect(containerVethFromName.Attrs().Index).To(Equal(containerVeth.Index))
 
                        return nil
                })
@@ -108,7 +108,7 @@ var _ = Describe("Link", func() {
 
                        hostVethFromName, err := netlink.LinkByName(hostVethName)
                        Expect(err).NotTo(HaveOccurred())
-                       Expect(hostVethFromName.Attrs().Index).To(Equal(hostVeth.Attrs().Index))
+                       Expect(hostVethFromName.Attrs().Index).To(Equal(hostVeth.Index))
 
                        return nil
                })
@@ -127,6 +127,20 @@ var _ = Describe("Link", func() {
                })
        })
 
+       Context("deleting an non-existent device", func() {
+               It("returns known error", func() {
+                       _ = containerNetNS.Do(func(ns.NetNS) error {
+                               defer GinkgoRecover()
+
+                               // This string should match the expected error codes in the cmdDel functions of some of the plugins
+                               _, err := ip.DelLinkByNameAddr("THIS_DONT_EXIST", netlink.FAMILY_V4)
+                               Expect(err).To(Equal(ip.ErrLinkNotFound))
+
+                               return nil
+                       })
+               })
+       })
+
        Context("when there is no name available for the host-side", func() {
                BeforeEach(func() {
                        //adding different interface to container ns
@@ -156,7 +170,7 @@ var _ = Describe("Link", func() {
 
                                hostVeth, _, err := ip.SetupVeth(containerVethName, mtu, hostNetNS)
                                Expect(err).NotTo(HaveOccurred())
-                               hostVethName = hostVeth.Attrs().Name
+                               hostVethName = hostVeth.Name
                                return nil
                        })
 
index 666cfe9..2833aba 100644 (file)
@@ -23,9 +23,9 @@ import (
        "github.com/containernetworking/cni/pkg/types"
 )
 
-const implementedSpecVersion string = "0.2.0"
+const ImplementedSpecVersion string = "0.2.0"
 
-var SupportedVersions = []string{"", "0.1.0", implementedSpecVersion}
+var SupportedVersions = []string{"", "0.1.0", ImplementedSpecVersion}
 
 // Compatibility types for CNI version 0.1.0 and 0.2.0
 
@@ -39,7 +39,7 @@ func NewResult(data []byte) (types.Result, error) {
 
 func GetResult(r types.Result) (*Result, error) {
        // We expect version 0.1.0/0.2.0 results
-       result020, err := r.GetAsVersion(implementedSpecVersion)
+       result020, err := r.GetAsVersion(ImplementedSpecVersion)
        if err != nil {
                return nil, err
        }
@@ -52,18 +52,20 @@ func GetResult(r types.Result) (*Result, error) {
 
 // Result is what gets returned from the plugin (via stdout) to the caller
 type Result struct {
-       IP4 *IPConfig `json:"ip4,omitempty"`
-       IP6 *IPConfig `json:"ip6,omitempty"`
-       DNS types.DNS `json:"dns,omitempty"`
+       CNIVersion string    `json:"cniVersion,omitempty"`
+       IP4        *IPConfig `json:"ip4,omitempty"`
+       IP6        *IPConfig `json:"ip6,omitempty"`
+       DNS        types.DNS `json:"dns,omitempty"`
 }
 
 func (r *Result) Version() string {
-       return implementedSpecVersion
+       return ImplementedSpecVersion
 }
 
 func (r *Result) GetAsVersion(version string) (types.Result, error) {
        for _, supportedVersion := range SupportedVersions {
                if version == supportedVersion {
+                       r.CNIVersion = version
                        return r, nil
                }
        }
index e686a9a..b5715fe 100644 (file)
@@ -24,9 +24,9 @@ import (
        "github.com/containernetworking/cni/pkg/types/020"
 )
 
-const implementedSpecVersion string = "0.3.0"
+const ImplementedSpecVersion string = "0.3.1"
 
-var SupportedVersions = []string{implementedSpecVersion}
+var SupportedVersions = []string{"0.3.0", ImplementedSpecVersion}
 
 func NewResult(data []byte) (types.Result, error) {
        result := &Result{}
@@ -37,7 +37,7 @@ func NewResult(data []byte) (types.Result, error) {
 }
 
 func GetResult(r types.Result) (*Result, error) {
-       resultCurrent, err := r.GetAsVersion(implementedSpecVersion)
+       resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
        if err != nil {
                return nil, err
        }
@@ -63,8 +63,9 @@ func convertFrom020(result types.Result) (*Result, error) {
        }
 
        newResult := &Result{
-               DNS:    oldResult.DNS,
-               Routes: []*types.Route{},
+               CNIVersion: ImplementedSpecVersion,
+               DNS:        oldResult.DNS,
+               Routes:     []*types.Route{},
        }
 
        if oldResult.IP4 != nil {
@@ -117,6 +118,7 @@ func convertFrom030(result types.Result) (*Result, error) {
        if !ok {
                return nil, fmt.Errorf("failed to convert result")
        }
+       newResult.CNIVersion = ImplementedSpecVersion
        return newResult, nil
 }
 
@@ -129,11 +131,12 @@ func NewResultFromResult(result types.Result) (*Result, error) {
                        }
                }
        }
-       return nil, fmt.Errorf("unsupported CNI result version %q", version)
+       return nil, fmt.Errorf("unsupported CNI result22 version %q", version)
 }
 
 // Result is what gets returned from the plugin (via stdout) to the caller
 type Result struct {
+       CNIVersion string         `json:"cniVersion,omitempty"`
        Interfaces []*Interface   `json:"interfaces,omitempty"`
        IPs        []*IPConfig    `json:"ips,omitempty"`
        Routes     []*types.Route `json:"routes,omitempty"`
@@ -143,7 +146,8 @@ type Result struct {
 // Convert to the older 0.2.0 CNI spec Result type
 func (r *Result) convertTo020() (*types020.Result, error) {
        oldResult := &types020.Result{
-               DNS: r.DNS,
+               CNIVersion: types020.ImplementedSpecVersion,
+               DNS:        r.DNS,
        }
 
        for _, ip := range r.IPs {
@@ -189,17 +193,18 @@ func (r *Result) convertTo020() (*types020.Result, error) {
 }
 
 func (r *Result) Version() string {
-       return implementedSpecVersion
+       return ImplementedSpecVersion
 }
 
 func (r *Result) GetAsVersion(version string) (types.Result, error) {
        switch version {
-       case implementedSpecVersion:
+       case "0.3.0", ImplementedSpecVersion:
+               r.CNIVersion = version
                return r, nil
        case types020.SupportedVersions[0], types020.SupportedVersions[1], types020.SupportedVersions[2]:
                return r.convertTo020()
        }
-       return nil, fmt.Errorf("cannot convert version 0.3.0 to %q", version)
+       return nil, fmt.Errorf("cannot convert version 0.3.x to %q", version)
 }
 
 func (r *Result) Print() error {
diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/sysctl/sysctl_linux.go b/vendor/github.com/containernetworking/cni/pkg/utils/sysctl/sysctl_linux.go
new file mode 100644 (file)
index 0000000..fe06d2d
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2016 CNI authors
+//
+// 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 sysctl
+
+import (
+       "fmt"
+       "io/ioutil"
+       "path/filepath"
+       "strings"
+)
+
+// Sysctl provides a method to set/get values from /proc/sys - in linux systems
+// new interface to set/get values of variables formerly handled by sysctl syscall
+// If optional `params` have only one string value - this function will
+// set this value into corresponding sysctl variable
+func Sysctl(name string, params ...string) (string, error) {
+       if len(params) > 1 {
+               return "", fmt.Errorf("unexcepted additional parameters")
+       } else if len(params) == 1 {
+               return setSysctl(name, params[0])
+       }
+       return getSysctl(name)
+}
+
+func getSysctl(name string) (string, error) {
+       fullName := filepath.Join("/proc/sys", strings.Replace(name, ".", "/", -1))
+       fullName = filepath.Clean(fullName)
+       data, err := ioutil.ReadFile(fullName)
+       if err != nil {
+               return "", err
+       }
+
+       return string(data[:len(data)-1]), nil
+}
+
+func setSysctl(name, value string) (string, error) {
+       fullName := filepath.Join("/proc/sys", strings.Replace(name, ".", "/", -1))
+       fullName = filepath.Clean(fullName)
+       if err := ioutil.WriteFile(fullName, []byte(value), 0644); err != nil {
+               return "", err
+       }
+
+       return getSysctl(name)
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go
new file mode 100644 (file)
index 0000000..33a2aa7
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2016 CNI authors
+//
+// 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 utils
+
+import (
+       "crypto/sha512"
+       "fmt"
+)
+
+const (
+       maxChainLength = 28
+       chainPrefix    = "CNI-"
+       prefixLength   = len(chainPrefix)
+)
+
+// Generates a chain name to be used with iptables.
+// Ensures that the generated chain name is exactly
+// maxChainLength chars in length
+func FormatChainName(name string, id string) string {
+       chainBytes := sha512.Sum512([]byte(name + id))
+       chain := fmt.Sprintf("%s%x", chainPrefix, chainBytes)
+       return chain[:maxChainLength]
+}
+
+// FormatComment returns a comment used for easier
+// rule identification within iptables.
+func FormatComment(name string, id string) string {
+       return fmt.Sprintf("name: %q id: %q", name, id)
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/utils_suite_test.go b/vendor/github.com/containernetworking/cni/pkg/utils/utils_suite_test.go
new file mode 100644 (file)
index 0000000..ee614a7
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2016 CNI authors
+//
+// 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 utils_test
+
+import (
+       . "github.com/onsi/ginkgo"
+       . "github.com/onsi/gomega"
+
+       "testing"
+)
+
+func TestUtils(t *testing.T) {
+       RegisterFailHandler(Fail)
+       RunSpecs(t, "Utils Suite")
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/utils_test.go b/vendor/github.com/containernetworking/cni/pkg/utils/utils_test.go
new file mode 100644 (file)
index 0000000..d703de4
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2016 CNI authors
+//
+// 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 utils
+
+import (
+       . "github.com/onsi/ginkgo"
+       . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Utils", func() {
+       It("must format a short name", func() {
+               chain := FormatChainName("test", "1234")
+               Expect(len(chain)).To(Equal(maxChainLength))
+               Expect(chain).To(Equal("CNI-2bbe0c48b91a7d1b8a6753a8"))
+       })
+
+       It("must truncate a long name", func() {
+               chain := FormatChainName("testalongnamethatdoesnotmakesense", "1234")
+               Expect(len(chain)).To(Equal(maxChainLength))
+               Expect(chain).To(Equal("CNI-374f33fe84ab0ed84dcdebe3"))
+       })
+
+       It("must be predictable", func() {
+               chain1 := FormatChainName("testalongnamethatdoesnotmakesense", "1234")
+               chain2 := FormatChainName("testalongnamethatdoesnotmakesense", "1234")
+               Expect(len(chain1)).To(Equal(maxChainLength))
+               Expect(len(chain2)).To(Equal(maxChainLength))
+               Expect(chain1).To(Equal(chain2))
+       })
+
+       It("must change when a character changes", func() {
+               chain1 := FormatChainName("testalongnamethatdoesnotmakesense", "1234")
+               chain2 := FormatChainName("testalongnamethatdoesnotmakesense", "1235")
+               Expect(len(chain1)).To(Equal(maxChainLength))
+               Expect(len(chain2)).To(Equal(maxChainLength))
+               Expect(chain1).To(Equal("CNI-374f33fe84ab0ed84dcdebe3"))
+               Expect(chain1).NotTo(Equal(chain2))
+       })
+})
index 7c58963..efe8ea8 100644 (file)
@@ -24,7 +24,7 @@ import (
 
 // Current reports the version of the CNI spec implemented by this library
 func Current() string {
-       return "0.3.0"
+       return "0.3.1"
 }
 
 // Legacy PluginInfo describes a plugin that is backwards compatible with the
@@ -35,7 +35,7 @@ func Current() string {
 // Any future CNI spec versions which meet this definition should be added to
 // this list.
 var Legacy = PluginSupports("0.1.0", "0.2.0")
-var All = PluginSupports("0.1.0", "0.2.0", "0.3.0")
+var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1")
 
 var resultFactories = []struct {
        supportedVersions []string