plugins: update to spec version 1.0.0

Signed-off-by: Dan Williams <dcbw@redhat.com>
This commit is contained in:
Dan Williams 2020-09-30 10:40:15 -05:00
parent 9e2430bb80
commit 7d8c767622
53 changed files with 350 additions and 373 deletions

View File

@ -23,7 +23,7 @@ import (
"github.com/Microsoft/hcsshim/hcn"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/errors"
)
@ -286,28 +286,20 @@ func ConstructResult(hnsNetwork *hcsshim.HNSNetwork, hnsEndpoint *hcsshim.HNSEnd
return nil, errors.Annotatef(err, "failed to parse CIDR from %s", hnsNetwork.Subnets[0].AddressPrefix)
}
var ipVersion string
if ipv4 := hnsEndpoint.IPAddress.To4(); ipv4 != nil {
ipVersion = "4"
} else if ipv6 := hnsEndpoint.IPAddress.To16(); ipv6 != nil {
ipVersion = "6"
} else {
return nil, fmt.Errorf("IPAddress of HNSEndpoint %s isn't a valid ipv4 or ipv6 Address", hnsEndpoint.Name)
}
resultIPConfig := &current.IPConfig{
Version: ipVersion,
Address: net.IPNet{
IP: hnsEndpoint.IPAddress,
Mask: ipSubnet.Mask},
Gateway: net.ParseIP(hnsEndpoint.GatewayAddress),
}
result := &current.Result{}
result.Interfaces = []*current.Interface{resultInterface}
result.IPs = []*current.IPConfig{resultIPConfig}
result.DNS = types.DNS{
Search: strings.Split(hnsEndpoint.DNSSuffix, ","),
Nameservers: strings.Split(hnsEndpoint.DNSServerList, ","),
result := &current.Result{
CNIVersion: current.ImplementedSpecVersion,
Interfaces: []*current.Interface{resultInterface},
IPs: []*current.IPConfig{resultIPConfig},
DNS: types.DNS{
Search: strings.Split(hnsEndpoint.DNSSuffix, ","),
Nameservers: strings.Split(hnsEndpoint.DNSServerList, ","),
},
}
return result, nil
@ -341,29 +333,21 @@ func ConstructHcnResult(hcnNetwork *hcn.HostComputeNetwork, hcnEndpoint *hcn.Hos
return nil, err
}
var ipVersion string
ipAddress := net.ParseIP(hcnEndpoint.IpConfigurations[0].IpAddress)
if ipv4 := ipAddress.To4(); ipv4 != nil {
ipVersion = "4"
} else if ipv6 := ipAddress.To16(); ipv6 != nil {
ipVersion = "6"
} else {
return nil, fmt.Errorf("[win-cni] The IPAddress of hnsEndpoint isn't a valid ipv4 or ipv6 Address.")
}
resultIPConfig := &current.IPConfig{
Version: ipVersion,
Address: net.IPNet{
IP: ipAddress,
Mask: ipSubnet.Mask},
Gateway: net.ParseIP(hcnEndpoint.Routes[0].NextHop),
}
result := &current.Result{}
result.Interfaces = []*current.Interface{resultInterface}
result.IPs = []*current.IPConfig{resultIPConfig}
result.DNS = types.DNS{
Search: hcnEndpoint.Dns.Search,
Nameservers: hcnEndpoint.Dns.ServerList,
result := &current.Result{
CNIVersion: current.ImplementedSpecVersion,
Interfaces: []*current.Interface{resultInterface},
IPs: []*current.IPConfig{resultIPConfig},
DNS: types.DNS{
Search: hcnEndpoint.Dns.Search,
Nameservers: hcnEndpoint.Dns.ServerList,
},
}
return result, nil

View File

@ -18,7 +18,7 @@ import (
"bytes"
"io/ioutil"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
)
func EnableIP4Forward() error {
@ -36,12 +36,13 @@ func EnableForward(ips []*current.IPConfig) error {
v6 := false
for _, ip := range ips {
if ip.Version == "4" && !v4 {
isV4 := ip.Address.IP.To4() != nil
if isV4 && !v4 {
if err := EnableIP4Forward(); err != nil {
return err
}
v4 = true
} else if ip.Version == "6" && !v6 {
} else if !isV4 && !v6 {
if err := EnableIP6Forward(); err != nil {
return err
}

View File

@ -21,7 +21,7 @@ import (
"net"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/vishvananda/netlink"
)
@ -57,15 +57,10 @@ func ValidateExpectedInterfaceIPs(ifName string, resultIPs []*current.IPConfig)
findGwy := &netlink.Route{Dst: ourPrefix}
routeFilter := netlink.RT_FILTER_DST
var family int
switch {
case ips.Version == "4":
family := netlink.FAMILY_V6
if ips.Address.IP.To4() != nil {
family = netlink.FAMILY_V4
case ips.Version == "6":
family = netlink.FAMILY_V6
default:
return fmt.Errorf("Invalid IP Version %v for interface %v", ips.Version, ifName)
}
gwy, err := netlink.RouteListFiltered(family, findGwy, routeFilter)

View File

@ -19,7 +19,7 @@ import (
"net"
"os"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ip"
"github.com/containernetworking/plugins/pkg/utils/sysctl"
@ -60,7 +60,7 @@ func ConfigureIface(ifName string, res *current.Result) error {
// Make sure sysctl "disable_ipv6" is 0 if we are about to add
// an IPv6 address to the interface
if !has_enabled_ipv6 && ipc.Version == "6" {
if !has_enabled_ipv6 && ipc.Address.IP.To4() == nil {
// Enabled IPv6 for loopback "lo" and the interface
// being configured
for _, iface := range [2]string{"lo", ifName} {

View File

@ -19,7 +19,7 @@ import (
"syscall"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -109,13 +109,11 @@ var _ = Describe("ConfigureIface", func() {
},
IPs: []*current.IPConfig{
{
Version: "4",
Interface: current.Int(0),
Address: *ipv4,
Gateway: ipgw4,
},
{
Version: "6",
Interface: current.Int(0),
Address: *ipv6,
Gateway: ipgw6,
@ -281,12 +279,10 @@ var _ = Describe("ConfigureIface", func() {
},
IPs: []*current.IPConfig{
{
Version: "4",
Address: *ipv4,
Gateway: ipgw4,
},
{
Version: "6",
Address: *ipv6,
Gateway: ipgw6,
},

View File

@ -17,13 +17,24 @@ package testutils
import (
"bytes"
"fmt"
"net"
"os/exec"
"strconv"
"syscall"
)
// Ping shells out to the `ping` command. Returns nil if successful.
func Ping(saddr, daddr string, isV6 bool, timeoutSec int) error {
func Ping(saddr, daddr string, timeoutSec int) error {
ip := net.ParseIP(saddr)
if ip == nil {
return fmt.Errorf("failed to parse IP %q", saddr)
}
bin := "ping6"
if ip.To4() != nil {
bin = "ping"
}
args := []string{
"-c", "1",
"-W", strconv.Itoa(timeoutSec),
@ -31,11 +42,6 @@ func Ping(saddr, daddr string, isV6 bool, timeoutSec int) error {
daddr,
}
bin := "ping"
if isV6 {
bin = "ping6"
}
cmd := exec.Command(bin, args...)
var stderr bytes.Buffer
cmd.Stderr = &stderr

View File

@ -30,7 +30,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/coreos/go-systemd/activation"
)
@ -81,7 +81,6 @@ func (d *DHCP) Allocate(args *skel.CmdArgs, result *current.Result) error {
d.setLease(clientID, l)
result.IPs = []*current.IPConfig{{
Version: "4",
Address: *ipn,
Gateway: l.Gateway(),
}}

View File

@ -23,7 +23,7 @@ import (
"time"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"

View File

@ -25,7 +25,7 @@ import (
"time"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"

View File

@ -26,7 +26,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
)
@ -69,7 +69,7 @@ func cmdAdd(args *skel.CmdArgs) error {
return err
}
result := &current.Result{}
result := &current.Result{CNIVersion: current.ImplementedSpecVersion}
if err := rpcCall("DHCP.Allocate", args, result); err != nil {
return err
}
@ -96,7 +96,7 @@ func cmdCheck(args *skel.CmdArgs) error {
return err
}
result := &current.Result{}
result := &current.Result{CNIVersion: current.ImplementedSpecVersion}
if err := rpcCall("DHCP.Allocate", args, result); err != nil {
return err
}

View File

@ -21,7 +21,7 @@ import (
"os"
"strconv"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ip"
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend"
)
@ -108,13 +108,8 @@ func (a *IPAllocator) Get(id string, ifname string, requestedIP net.IP) (*curren
if reservedIP == nil {
return nil, fmt.Errorf("no IP addresses available in range set: %s", a.rangeset.String())
}
version := "4"
if reservedIP.IP.To4() == nil {
version = "6"
}
return &current.IPConfig{
Version: version,
Address: *reservedIP,
Gateway: gw,
}, nil

View File

@ -19,7 +19,7 @@ import (
"net"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
fakestore "github.com/containernetworking/plugins/plugins/ipam/host-local/backend/testing"
. "github.com/onsi/ginkgo"

View File

@ -20,7 +20,7 @@ import (
"net"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/020"
"github.com/containernetworking/cni/pkg/version"
)
// The top-level network config - IPAM plugins are passed the full configuration
@ -136,10 +136,8 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
// CNI spec 0.2.0 and below supported only one v4 and v6 address
if numV4 > 1 || numV6 > 1 {
for _, v := range types020.SupportedVersions {
if n.CNIVersion == v {
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
}
if ok, _ := version.GreaterThanOrEqualTo(n.CNIVersion, "0.3.0"); !ok {
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
}
}

View File

@ -25,7 +25,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/020"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/testutils"
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/disk"
@ -89,14 +89,12 @@ var _ = Describe("host-local Operations", func() {
// Gomega is cranky about slices with different caps
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("10.1.2.2/24"),
Gateway: net.ParseIP("10.1.2.1"),
}))
Expect(*result.IPs[1]).To(Equal(
current.IPConfig{
Version: "6",
Address: mustCIDR("2001:db8:1::2/64"),
Gateway: net.ParseIP("2001:db8:1::1"),
},
@ -487,7 +485,7 @@ var _ = Describe("host-local Operations", func() {
Expect(err).NotTo(HaveOccurred())
Expect(string(contents)).To(Equal("10.1.2.2"))
Expect(result.DNS).To(Equal(types.DNS{Nameservers: []string{"192.0.2.3"}}))
Expect(result.DNS.Nameservers).To(Equal([]string{"192.0.2.3"}))
// Release the IP
err = testutils.CmdDelWithArgs(args, func() error {

View File

@ -25,7 +25,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
)
@ -62,7 +62,7 @@ func cmdAdd(args *skel.CmdArgs) error {
return err
}
result := &current.Result{}
result := &current.Result{CNIVersion: current.ImplementedSpecVersion}
if ipamConf.ResolvConf != "" {
dns, err := parseResolvConf(ipamConf.ResolvConf)

View File

@ -22,8 +22,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
types020 "github.com/containernetworking/cni/pkg/types/020"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
)
@ -225,20 +224,16 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
}
if n.IPAM.Addresses[i].Address.IP.To4() != nil {
n.IPAM.Addresses[i].Version = "4"
numV4++
} else {
n.IPAM.Addresses[i].Version = "6"
numV6++
}
}
// CNI spec 0.2.0 and below supported only one v4 and v6 address
if numV4 > 1 || numV6 > 1 {
for _, v := range types020.SupportedVersions {
if n.CNIVersion == v {
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
}
if ok, _ := version.GreaterThanOrEqualTo(n.CNIVersion, "0.3.0"); !ok {
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
}
}
@ -254,14 +249,16 @@ func cmdAdd(args *skel.CmdArgs) error {
return err
}
result := &current.Result{}
result.DNS = ipamConf.DNS
result.Routes = ipamConf.Routes
result := &current.Result{
CNIVersion: current.ImplementedSpecVersion,
DNS: ipamConf.DNS,
Routes: ipamConf.Routes,
}
for _, v := range ipamConf.Addresses {
result.IPs = append(result.IPs, &current.IPConfig{
Version: v.Version,
Address: v.Address,
Gateway: v.Gateway})
Gateway: v.Gateway,
})
}
return types.PrintResult(result, confVersion)

View File

@ -20,7 +20,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/testutils"
. "github.com/onsi/ginkgo"
@ -79,14 +79,12 @@ var _ = Describe("static Operations", func() {
// Gomega is cranky about slices with different caps
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("10.10.0.1/24"),
Gateway: net.ParseIP("10.10.0.254"),
}))
Expect(*result.IPs[1]).To(Equal(
current.IPConfig{
Version: "6",
Address: mustCIDR("3ffe:ffff:0:01ff::1/64"),
Gateway: net.ParseIP("3ffe:ffff:0::1"),
},
@ -192,7 +190,6 @@ var _ = Describe("static Operations", func() {
// Gomega is cranky about slices with different caps
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("10.10.0.1/24"),
Gateway: net.ParseIP("10.10.0.254"),
}))
@ -246,13 +243,11 @@ var _ = Describe("static Operations", func() {
// Gomega is cranky about slices with different caps
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("10.10.0.1/24"),
Gateway: net.ParseIP("10.10.0.254"),
}))
Expect(*result.IPs[1]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("11.11.0.1/24"),
Gateway: nil,
}))
@ -313,12 +308,10 @@ var _ = Describe("static Operations", func() {
// Gomega is cranky about slices with different caps
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("10.10.0.1/24"),
}))
Expect(*result.IPs[1]).To(Equal(
current.IPConfig{
Version: "6",
Address: mustCIDR("3ffe:ffff:0:01ff::1/64"),
},
))
@ -383,12 +376,10 @@ var _ = Describe("static Operations", func() {
// Gomega is cranky about slices with different caps
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("10.10.0.1/24"),
}))
Expect(*result.IPs[1]).To(Equal(
current.IPConfig{
Version: "6",
Address: mustCIDR("3ffe:ffff:0:01ff::1/64"),
},
))
@ -458,12 +449,10 @@ var _ = Describe("static Operations", func() {
// only addresses in runtimeConfig configured because of its priorities
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
Version: "4",
Address: mustCIDR("10.10.0.1/24"),
}))
Expect(*result.IPs[1]).To(Equal(
current.IPConfig{
Version: "6",
Address: mustCIDR("3ffe:ffff:0:01ff::1/64"),
},
))

View File

@ -29,7 +29,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"
"github.com/containernetworking/plugins/pkg/ipam"
@ -412,7 +412,14 @@ func cmdAdd(args *skel.CmdArgs) error {
}
// Assume L2 interface only
result := &current.Result{CNIVersion: cniVersion, Interfaces: []*current.Interface{brInterface, hostInterface, containerInterface}}
result := &current.Result{
CNIVersion: current.ImplementedSpecVersion,
Interfaces: []*current.Interface{
brInterface,
hostInterface,
containerInterface,
},
}
if isLayer3 {
// run the IPAM plugin and get back the config to apply
@ -453,7 +460,7 @@ func cmdAdd(args *skel.CmdArgs) error {
// bridge. Hairpin mode causes echos of neighbor solicitation
// packets, which causes DAD failures.
for _, ipc := range result.IPs {
if ipc.Version == "6" && (n.HairpinMode || n.PromiscMode) {
if ipc.Address.IP.To4() == nil && (n.HairpinMode || n.PromiscMode) {
if err := disableIPV6DAD(args.IfName); err != nil {
return err
}
@ -496,7 +503,7 @@ func cmdAdd(args *skel.CmdArgs) error {
}
for _, ipc := range result.IPs {
if ipc.Version == "4" {
if ipc.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
}
}

View File

@ -27,8 +27,9 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
types020 "github.com/containernetworking/cni/pkg/types/020"
"github.com/containernetworking/cni/pkg/types/current"
types040 "github.com/containernetworking/cni/pkg/types/040"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -350,7 +351,7 @@ func checkVlan(vlanId int, bridgeVlanInfo []*nl.BridgeVlanInfo) bool {
type cmdAddDelTester interface {
setNS(testNS ns.NetNS, targetNS ns.NetNS)
cmdAddTest(tc testCase, dataDir string) (*current.Result, error)
cmdAddTest(tc testCase, dataDir string) (types.Result, error)
cmdCheckTest(tc testCase, conf *Net, dataDir string)
cmdDelTest(tc testCase, dataDir string)
}
@ -378,12 +379,12 @@ func (tester *testerV04x) setNS(testNS ns.NetNS, targetNS ns.NetNS) {
tester.targetNS = targetNS
}
func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (*current.Result, error) {
func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (types.Result, error) {
// Generate network config and command arguments
tester.args = tc.createCmdArgs(tester.targetNS, dataDir)
// Execute cmdADD on the plugin
var result *current.Result
var result *types040.Result
err := tester.testNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
@ -393,8 +394,9 @@ func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (*current.Resu
Expect(err).NotTo(HaveOccurred())
Expect(strings.Index(string(raw), "\"interfaces\":")).Should(BeNumerically(">", 0))
result, err = current.GetResult(r)
resultType, err := r.GetAsVersion(tc.cniVersion)
Expect(err).NotTo(HaveOccurred())
result = resultType.(*types040.Result)
Expect(len(result.Interfaces)).To(Equal(3))
Expect(result.Interfaces[0].Name).To(Equal(BRNAME))
@ -635,12 +637,12 @@ func (tester *testerV03x) setNS(testNS ns.NetNS, targetNS ns.NetNS) {
tester.targetNS = targetNS
}
func (tester *testerV03x) cmdAddTest(tc testCase, dataDir string) (*current.Result, error) {
func (tester *testerV03x) cmdAddTest(tc testCase, dataDir string) (types.Result, error) {
// Generate network config and command arguments
tester.args = tc.createCmdArgs(tester.targetNS, dataDir)
// Execute cmdADD on the plugin
var result *current.Result
var result *types040.Result
err := tester.testNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
@ -650,8 +652,9 @@ func (tester *testerV03x) cmdAddTest(tc testCase, dataDir string) (*current.Resu
Expect(err).NotTo(HaveOccurred())
Expect(strings.Index(string(raw), "\"interfaces\":")).Should(BeNumerically(">", 0))
result, err = current.GetResult(r)
resultType, err := r.GetAsVersion(tc.cniVersion)
Expect(err).NotTo(HaveOccurred())
result = resultType.(*types040.Result)
if !tc.isLayer2 && tc.vlan != 0 {
Expect(len(result.Interfaces)).To(Equal(4))
@ -870,7 +873,7 @@ func (tester *testerV01xOr02x) setNS(testNS ns.NetNS, targetNS ns.NetNS) {
tester.targetNS = targetNS
}
func (tester *testerV01xOr02x) cmdAddTest(tc testCase, dataDir string) (*current.Result, error) {
func (tester *testerV01xOr02x) cmdAddTest(tc testCase, dataDir string) (types.Result, error) {
// Generate network config and calculate gateway addresses
tester.args = tc.createCmdArgs(tester.targetNS, dataDir)
@ -885,7 +888,7 @@ func (tester *testerV01xOr02x) cmdAddTest(tc testCase, dataDir string) (*current
Expect(strings.Index(string(raw), "\"ip\":")).Should(BeNumerically(">", 0))
// We expect a version 0.1.0 result
_, err = types020.GetResult(r)
_, err = r.GetAsVersion(tc.cniVersion)
Expect(err).NotTo(HaveOccurred())
// Make sure bridge link exists
@ -1006,7 +1009,9 @@ func cmdAddDelTest(testNS ns.NetNS, tc testCase, dataDir string) {
result, err := tester.cmdAddTest(tc, dataDir)
Expect(err).NotTo(HaveOccurred())
if strings.HasPrefix(tc.cniVersion, "0.3.") {
greater, err := version.GreaterThanOrEqualTo(tc.cniVersion, "0.3.0")
Expect(err).NotTo(HaveOccurred())
if greater {
Expect(result).NotTo(BeNil())
} else {
Expect(result).To(BeNil())
@ -1527,18 +1532,24 @@ var _ = Describe("bridge Operations", func() {
}
for _, tc := range testCases {
tc.cniVersion = "0.3.1"
_, _, err := setupBridge(tc.netConf())
Expect(err).NotTo(HaveOccurred())
link, err := netlink.LinkByName(BRNAME)
Expect(err).NotTo(HaveOccurred())
origMac := link.Attrs().HardwareAddr
err := originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
cmdAddDelTest(originalNS, tc, dataDir)
tc.cniVersion = "0.3.1"
_, _, err := setupBridge(tc.netConf())
Expect(err).NotTo(HaveOccurred())
link, err := netlink.LinkByName(BRNAME)
Expect(err).NotTo(HaveOccurred())
origMac := link.Attrs().HardwareAddr
link, err = netlink.LinkByName(BRNAME)
cmdAddDelTest(originalNS, tc, dataDir)
link, err = netlink.LinkByName(BRNAME)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origMac))
return nil
})
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(origMac))
}
})

View File

@ -30,7 +30,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"

View File

@ -23,8 +23,9 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
types020 "github.com/containernetworking/cni/pkg/types/020"
"github.com/containernetworking/cni/pkg/types/current"
types040 "github.com/containernetworking/cni/pkg/types/040"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -110,10 +111,8 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
}
if n.IPAM.Addresses[i].Address.IP.To4() != nil {
n.IPAM.Addresses[i].Version = "4"
numV4++
} else {
n.IPAM.Addresses[i].Version = "6"
numV6++
}
}
@ -136,10 +135,8 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
addr := Address{Address: net.IPNet{IP: ip, Mask: subnet.Mask}}
if addr.Address.IP.To4() != nil {
addr.Version = "4"
numV4++
} else {
addr.Version = "6"
numV6++
}
n.IPAM.Addresses = append(n.IPAM.Addresses, addr)
@ -164,10 +161,8 @@ func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error) {
// CNI spec 0.2.0 and below supported only one v4 and v6 address
if numV4 > 1 || numV6 > 1 {
for _, v := range types020.SupportedVersions {
if n.CNIVersion == v {
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
}
if ok, _ := version.GreaterThanOrEqualTo(n.CNIVersion, "0.3.0"); !ok {
return nil, "", fmt.Errorf("CNI version %v does not support more than 1 address per family", n.CNIVersion)
}
}
@ -262,11 +257,11 @@ var _ = Describe("base functionality", func() {
cniName := "eth0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.0",
"cniVersion": "%s",
"name": "cni-plugin-host-device-test",
"type": "host-device",
"device": %q
}`, ifname)
}`, current.ImplementedSpecVersion, ifname)
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNS.Path(),
@ -352,11 +347,11 @@ var _ = Describe("base functionality", func() {
cniName := "eth0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.0",
"cniVersion": "%s",
"name": "cni-plugin-host-device-test",
"type": "host-device",
"device": %q
}`, ifname)
}`, current.ImplementedSpecVersion, ifname)
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNS.Path(),
@ -487,7 +482,7 @@ var _ = Describe("base functionality", func() {
targetIP := "10.10.0.1/24"
cniName := "eth0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.0",
"cniVersion": "%s",
"name": "cni-plugin-host-device-test",
"type": "host-device",
"ipam": {
@ -499,7 +494,7 @@ var _ = Describe("base functionality", func() {
}]
},
"device": %q
}`, ifname)
}`, current.ImplementedSpecVersion, ifname)
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNS.Path(),
@ -566,11 +561,11 @@ var _ = Describe("base functionality", func() {
})
It("fails an invalid config", func() {
conf := `{
"cniVersion": "0.3.0",
conf := fmt.Sprintf(`{
"cniVersion": "%s",
"name": "cni-plugin-host-device-test",
"type": "host-device"
}`
}`, current.ImplementedSpecVersion)
args := &skel.CmdArgs{
ContainerID: "dummy",
@ -629,9 +624,9 @@ var _ = Describe("base functionality", func() {
Expect(err).NotTo(HaveOccurred())
// check that the result was sane
res, err := current.NewResultFromResult(resI)
res, err := types040.GetResult(resI)
Expect(err).NotTo(HaveOccurred())
Expect(res.Interfaces).To(Equal([]*current.Interface{
Expect(res.Interfaces).To(Equal([]*types040.Interface{
{
Name: cniName,
Mac: origLink.Attrs().HardwareAddr.String(),
@ -748,9 +743,9 @@ var _ = Describe("base functionality", func() {
Expect(err).NotTo(HaveOccurred())
// check that the result was sane
res, err := current.NewResultFromResult(resI)
res, err := types040.GetResult(resI)
Expect(err).NotTo(HaveOccurred())
Expect(res.Interfaces).To(Equal([]*current.Interface{
Expect(res.Interfaces).To(Equal([]*types040.Interface{
{
Name: cniName,
Mac: origLink.Attrs().HardwareAddr.String(),
@ -873,9 +868,9 @@ var _ = Describe("base functionality", func() {
Expect(err).NotTo(HaveOccurred())
// check that the result is sane
res, err := current.NewResultFromResult(resI)
res, err := types040.GetResult(resI)
Expect(err).NotTo(HaveOccurred())
Expect(res.Interfaces).To(Equal([]*current.Interface{
Expect(res.Interfaces).To(Equal([]*types040.Interface{
{
Name: cniName,
Mac: origLink.Attrs().HardwareAddr.String(),

View File

@ -24,7 +24,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"

View File

@ -22,7 +22,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -105,21 +105,22 @@ func ipvlanAddDelTest(conf, IFNAME string, originalNS ns.NetNS) {
StdinData: []byte(conf),
}
var result *current.Result
var result types.Result
var curResult *current.Result
err = originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
r, _, err := testutils.CmdAddWithArgs(args, func() error {
result, _, err = testutils.CmdAddWithArgs(args, func() error {
return cmdAdd(args)
})
Expect(err).NotTo(HaveOccurred())
result, err = current.GetResult(r)
curResult, err = current.GetResult(result)
Expect(err).NotTo(HaveOccurred())
Expect(len(result.Interfaces)).To(Equal(1))
Expect(result.Interfaces[0].Name).To(Equal(IFNAME))
Expect(len(result.IPs)).To(Equal(1))
Expect(len(curResult.Interfaces)).To(Equal(1))
Expect(curResult.Interfaces[0].Name).To(Equal(IFNAME))
Expect(len(curResult.IPs)).To(Equal(1))
return nil
})
Expect(err).NotTo(HaveOccurred())
@ -132,7 +133,7 @@ func ipvlanAddDelTest(conf, IFNAME string, originalNS ns.NetNS) {
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().Name).To(Equal(IFNAME))
hwaddr, err := net.ParseMAC(result.Interfaces[0].Mac)
hwaddr, err := net.ParseMAC(curResult.Interfaces[0].Mac)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))
@ -178,21 +179,22 @@ func ipvlanAddCheckDelTest(conf string, netName string, IFNAME string, originalN
StdinData: []byte(conf),
}
var result *current.Result
var result types.Result
var curResult *current.Result
err = originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
r, _, err := testutils.CmdAddWithArgs(args, func() error {
result, _, err = testutils.CmdAddWithArgs(args, func() error {
return cmdAdd(args)
})
Expect(err).NotTo(HaveOccurred())
result, err = current.GetResult(r)
curResult, err = current.GetResult(result)
Expect(err).NotTo(HaveOccurred())
Expect(len(result.Interfaces)).To(Equal(1))
Expect(result.Interfaces[0].Name).To(Equal(IFNAME))
Expect(len(result.IPs)).To(Equal(1))
Expect(len(curResult.Interfaces)).To(Equal(1))
Expect(curResult.Interfaces[0].Name).To(Equal(IFNAME))
Expect(len(curResult.IPs)).To(Equal(1))
return nil
})
Expect(err).NotTo(HaveOccurred())
@ -205,7 +207,7 @@ func ipvlanAddCheckDelTest(conf string, netName string, IFNAME string, originalN
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().Name).To(Equal(IFNAME))
hwaddr, err := net.ParseMAC(result.Interfaces[0].Mac)
hwaddr, err := net.ParseMAC(curResult.Interfaces[0].Mac)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))

View File

@ -24,7 +24,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ns"
@ -109,12 +109,19 @@ func cmdAdd(args *skel.CmdArgs) error {
// loopback should pass it transparently
result = conf.PrevResult
} else {
loopbackInterface := &current.Interface{Name: args.IfName, Mac: "00:00:00:00:00:00", Sandbox: args.Netns}
r := &current.Result{CNIVersion: conf.CNIVersion, Interfaces: []*current.Interface{loopbackInterface}}
r := &current.Result{
CNIVersion: conf.CNIVersion,
Interfaces: []*current.Interface{
&current.Interface{
Name: args.IfName,
Mac: "00:00:00:00:00:00",
Sandbox: args.Netns,
},
},
}
if v4Addr != nil {
r.IPs = append(r.IPs, &current.IPConfig{
Version: "4",
Interface: current.Int(0),
Address: *v4Addr,
})
@ -122,7 +129,6 @@ func cmdAdd(args *skel.CmdArgs) error {
if v6Addr != nil {
r.IPs = append(r.IPs, &current.IPConfig{
Version: "6",
Interface: current.Int(0),
Address: *v6Addr,
})

View File

@ -26,7 +26,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"
@ -269,7 +269,10 @@ func cmdAdd(args *skel.CmdArgs) error {
}()
// Assume L2 interface only
result := &current.Result{CNIVersion: cniVersion, Interfaces: []*current.Interface{macvlanInterface}}
result := &current.Result{
CNIVersion: current.ImplementedSpecVersion,
Interfaces: []*current.Interface{macvlanInterface},
}
if isLayer3 {
// run the IPAM plugin and get back the config to apply
@ -314,7 +317,7 @@ func cmdAdd(args *skel.CmdArgs) error {
}
for _, ipc := range result.IPs {
if ipc.Version == "4" {
if ipc.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
}
}

View File

@ -22,7 +22,8 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
types040 "github.com/containernetworking/cni/pkg/types/040"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -129,7 +130,7 @@ var _ = Describe("macvlan Operations", func() {
It("creates an macvlan link in a non-default namespace", func() {
conf := &NetConf{
NetConf: types.NetConf{
CNIVersion: "0.3.1",
CNIVersion: current.ImplementedSpecVersion,
Name: "testConfig",
Type: "macvlan",
},
@ -167,7 +168,7 @@ var _ = Describe("macvlan Operations", func() {
const IFNAME = "macvl0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.1",
"cniVersion": "%s",
"name": "mynet",
"type": "macvlan",
"master": "%s",
@ -175,7 +176,7 @@ var _ = Describe("macvlan Operations", func() {
"type": "host-local",
"subnet": "10.1.2.0/24"
}
}`, MASTER_NAME)
}`, current.ImplementedSpecVersion, MASTER_NAME)
targetNs, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
@ -253,7 +254,7 @@ var _ = Describe("macvlan Operations", func() {
const IFNAME = "macvl0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.0",
"cniVersion": "%s",
"name": "mynet",
"type": "macvlan",
"master": "%s",
@ -261,7 +262,7 @@ var _ = Describe("macvlan Operations", func() {
"type": "host-local",
"subnet": "10.1.2.0/24"
}
}`, MASTER_NAME)
}`, current.ImplementedSpecVersion, MASTER_NAME)
targetNs, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
@ -291,12 +292,12 @@ var _ = Describe("macvlan Operations", func() {
const IFNAME = "macvl0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.1",
"cniVersion": "%s",
"name": "mynet",
"type": "macvlan",
"master": "%s",
"ipam": {}
}`, MASTER_NAME)
}`, current.ImplementedSpecVersion, MASTER_NAME)
targetNs, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
@ -395,7 +396,7 @@ var _ = Describe("macvlan Operations", func() {
StdinData: []byte(conf),
}
var result *current.Result
var result *types040.Result
err = originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
@ -404,7 +405,7 @@ var _ = Describe("macvlan Operations", func() {
})
Expect(err).NotTo(HaveOccurred())
result, err = current.GetResult(r)
result, err = types040.GetResult(r)
Expect(err).NotTo(HaveOccurred())
Expect(len(result.Interfaces)).To(Equal(1))
@ -487,15 +488,15 @@ var _ = Describe("macvlan Operations", func() {
It("configures and deconfigures a macvlan link with ADD/DEL, without master config", func() {
const IFNAME = "macvl0"
conf := `{
"cniVersion": "0.3.1",
conf := fmt.Sprintf(`{
"cniVersion": "%s",
"name": "mynet",
"type": "macvlan",
"ipam": {
"type": "host-local",
"subnet": "10.1.2.0/24"
}
}`
}`, current.ImplementedSpecVersion)
targetNs, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
@ -598,7 +599,7 @@ var _ = Describe("macvlan Operations", func() {
const IFNAME = "macvl0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.1",
"cniVersion": "0.4.0",
"name": "mynet",
"type": "macvlan",
"master": "%s",
@ -617,7 +618,7 @@ var _ = Describe("macvlan Operations", func() {
Args: "IgnoreUnknown=true;MAC=c2:11:22:33:44:55",
}
var result *current.Result
var result *types040.Result
err = originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
@ -626,7 +627,7 @@ var _ = Describe("macvlan Operations", func() {
})
Expect(err).NotTo(HaveOccurred())
result, err = current.GetResult(r)
result, err = types040.GetResult(r)
Expect(err).NotTo(HaveOccurred())
Expect(len(result.Interfaces)).To(Equal(1))
@ -683,7 +684,7 @@ var _ = Describe("macvlan Operations", func() {
const IFNAME = "macvl0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.1",
"cniVersion": "%s",
"capabilities": {"mac": true},
"RuntimeConfig": {
"mac": "c2:11:22:33:44:55"
@ -692,7 +693,7 @@ var _ = Describe("macvlan Operations", func() {
"type": "macvlan",
"master": "%s",
"ipam": {}
}`, MASTER_NAME)
}`, current.ImplementedSpecVersion, MASTER_NAME)
targetNs, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())

View File

@ -27,7 +27,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"
@ -108,7 +108,7 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
}
addrBits := 32
if ipc.Version == "6" {
if ipc.Address.IP.To4() == nil {
addrBits = 128
}
@ -141,7 +141,7 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
// Send a gratuitous arp for all v4 addresses
for _, ipc := range pr.IPs {
if ipc.Version == "4" {
if ipc.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
}
}

View File

@ -21,7 +21,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -155,7 +155,7 @@ var _ = Describe("ptp Operations", func() {
daddr := ipc.Gateway.String()
fmt.Fprintln(GinkgoWriter, "ping", saddr, "->", daddr)
if err := testutils.Ping(saddr, daddr, (ipc.Version == "6"), 30); err != nil {
if err := testutils.Ping(saddr, daddr, 30); err != nil {
return fmt.Errorf("ping %s -> %s failed: %s", saddr, daddr, err)
}
}
@ -257,7 +257,7 @@ var _ = Describe("ptp Operations", func() {
daddr := ipc.Gateway.String()
fmt.Fprintln(GinkgoWriter, "ping", saddr, "->", daddr)
if err := testutils.Ping(saddr, daddr, (ipc.Version == "6"), 30); err != nil {
if err := testutils.Ping(saddr, daddr, 30); err != nil {
return fmt.Errorf("ping %s -> %s failed: %s", saddr, daddr, err)
}
}
@ -288,7 +288,7 @@ var _ = Describe("ptp Operations", func() {
Expect(err).NotTo(HaveOccurred())
cniVersion := "0.4.0"
newConf, err := buildOneConfig(netName, cniVersion, n, res)
newConf, err := buildOneConfig(netName, cniVersion, n, resI)
Expect(err).NotTo(HaveOccurred())
confString, err := json.Marshal(newConf)
@ -484,8 +484,8 @@ var _ = Describe("ptp Operations", func() {
It("deconfigures an unconfigured ptp link with DEL", func() {
const IFNAME = "ptp0"
conf := `{
"cniVersion": "0.3.0",
conf := fmt.Sprintf(`{
"cniVersion": "%s",
"name": "mynet",
"type": "ptp",
"ipMasq": true,
@ -494,7 +494,7 @@ var _ = Describe("ptp Operations", func() {
"type": "host-local",
"subnet": "10.1.2.0/24"
}
}`
}`, current.ImplementedSpecVersion)
targetNs, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())

View File

@ -24,7 +24,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"

View File

@ -22,7 +22,8 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/cni/pkg/types/040"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -127,7 +128,7 @@ var _ = Describe("vlan Operations", func() {
It("creates an vlan link in a non-default namespace with given MTU", func() {
conf := &NetConf{
NetConf: types.NetConf{
CNIVersion: "0.3.0",
CNIVersion: current.ImplementedSpecVersion,
Name: "testConfig",
Type: "vlan",
},
@ -167,7 +168,7 @@ var _ = Describe("vlan Operations", func() {
It("creates an vlan link in a non-default namespace with master's MTU", func() {
conf := &NetConf{
NetConf: types.NetConf{
CNIVersion: "0.3.0",
CNIVersion: current.ImplementedSpecVersion,
Name: "testConfig",
Type: "vlan",
},
@ -212,7 +213,7 @@ var _ = Describe("vlan Operations", func() {
const IFNAME = "eth0"
conf := fmt.Sprintf(`{
"cniVersion": "0.3.0",
"cniVersion": "%s",
"name": "mynet",
"type": "vlan",
"master": "%s",
@ -220,7 +221,7 @@ var _ = Describe("vlan Operations", func() {
"type": "host-local",
"subnet": "10.1.2.0/24"
}
}`, MASTER_NAME)
}`, current.ImplementedSpecVersion, MASTER_NAME)
targetNs, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
@ -307,7 +308,7 @@ var _ = Describe("vlan Operations", func() {
Expect(err).NotTo(HaveOccurred())
})
It("configures and deconfigures an CNI V4 vlan link with ADD/CHECK/DEL", func() {
It("configures and deconfigures an CNI v0.4.0 vlan link with ADD/CHECK/DEL", func() {
const IFNAME = "eth0"
conf := fmt.Sprintf(`{
@ -333,7 +334,7 @@ var _ = Describe("vlan Operations", func() {
StdinData: []byte(conf),
}
var result *current.Result
var result *types040.Result
err = originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()
@ -342,7 +343,7 @@ var _ = Describe("vlan Operations", func() {
})
Expect(err).NotTo(HaveOccurred())
result, err = current.GetResult(r)
result, err = types040.GetResult(r)
Expect(err).NotTo(HaveOccurred())
Expect(len(result.Interfaces)).To(Equal(1))
@ -423,8 +424,8 @@ var _ = Describe("vlan Operations", func() {
})
Describe("fails to create vlan link with invalid MTU", func() {
conf := `{
"cniVersion": "0.3.1",
confFmt := `{
"cniVersion": "%s",
"name": "mynet",
"type": "vlan",
"master": "%s",
@ -457,7 +458,7 @@ var _ = Describe("vlan Operations", func() {
ContainerID: "dummy",
Netns: "/var/run/netns/test",
IfName: "eth0",
StdinData: []byte(fmt.Sprintf(conf, MASTER_NAME, 1600)),
StdinData: []byte(fmt.Sprintf(confFmt, current.ImplementedSpecVersion, MASTER_NAME, 1600)),
}
_ = originalNS.Do(func(netNS ns.NetNS) error {
@ -478,7 +479,7 @@ var _ = Describe("vlan Operations", func() {
ContainerID: "dummy",
Netns: "/var/run/netns/test",
IfName: "eth0",
StdinData: []byte(fmt.Sprintf(conf, MASTER_NAME, -100)),
StdinData: []byte(fmt.Sprintf(confFmt, current.ImplementedSpecVersion, MASTER_NAME, -100)),
}
_ = originalNS.Do(func(netNS ns.NetNS) error {

View File

@ -25,7 +25,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/errors"

View File

@ -24,7 +24,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/errors"

View File

@ -26,7 +26,8 @@ import (
"github.com/containernetworking/cni/pkg/invoke"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/cni/pkg/types/040"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -160,7 +161,7 @@ var _ = Describe("bandwidth test", func() {
defer GinkgoRecover()
r, out, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
Expect(err).NotTo(HaveOccurred(), string(out))
result, err := current.GetResult(r)
result, err := types040.GetResult(r)
Expect(err).NotTo(HaveOccurred())
Expect(result.Interfaces).To(HaveLen(3))
@ -451,7 +452,7 @@ var _ = Describe("bandwidth test", func() {
defer GinkgoRecover()
r, out, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
Expect(err).NotTo(HaveOccurred(), string(out))
result, err := current.GetResult(r)
result, err := types040.GetResult(r)
Expect(err).NotTo(HaveOccurred())
Expect(result.Interfaces).To(HaveLen(3))
@ -693,7 +694,7 @@ var _ = Describe("bandwidth test", func() {
defer GinkgoRecover()
r, out, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
Expect(err).NotTo(HaveOccurred(), string(out))
result, err := current.GetResult(r)
result, err := types040.GetResult(r)
Expect(err).NotTo(HaveOccurred())
Expect(result.Interfaces).To(HaveLen(5))
@ -908,8 +909,8 @@ var _ = Describe("bandwidth test", func() {
burstInBits = rateInBits * 2
packetInBytes = rateInBytes * 25
ptpConf = `{
"cniVersion": "0.3.0",
ptpConf = fmt.Sprintf(`{
"cniVersion": "%s",
"name": "mynet",
"type": "ptp",
"ipMasq": true,
@ -918,7 +919,7 @@ var _ = Describe("bandwidth test", func() {
"type": "host-local",
"subnet": "10.1.2.0/24"
}
}`
}`, current.ImplementedSpecVersion)
containerWithTbfIFName := "ptp0"
containerWithoutTbfIFName := "ptp1"
@ -1099,7 +1100,7 @@ var _ = Describe("bandwidth test", func() {
})
Expect(err).NotTo(HaveOccurred())
containerWithTbfResult, err := current.GetResult(containerWithTbfRes)
containerWithTbfResult, err := types040.GetResult(containerWithTbfRes)
Expect(err).NotTo(HaveOccurred())
tbfPluginConf := &PluginConf{}
@ -1181,7 +1182,7 @@ var _ = Describe("bandwidth test", func() {
By("gather timing statistics about both containers")
By("sending tcp traffic to the container that has traffic shaped", func() {
runtimeWithLimit = b.Time("with tbf", func() {
result, err := current.GetResult(containerWithTbfRes)
result, err := types040.GetResult(containerWithTbfRes)
Expect(err).NotTo(HaveOccurred())
makeTcpClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithTbf, packetInBytes)
@ -1190,7 +1191,7 @@ var _ = Describe("bandwidth test", func() {
By("sending tcp traffic to the container that does not have traffic shaped", func() {
runtimeWithoutLimit = b.Time("without tbf", func() {
result, err := current.GetResult(containerWithoutTbfRes)
result, err := types040.GetResult(containerWithoutTbfRes)
Expect(err).NotTo(HaveOccurred())
makeTcpClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithoutTbf, packetInBytes)

View File

@ -23,7 +23,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ip"

View File

@ -24,7 +24,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
@ -130,7 +130,9 @@ func cmdAdd(args *skel.CmdArgs) error {
}
if result == nil {
result = &current.Result{}
result = &current.Result{
CNIVersion: current.ImplementedSpecVersion,
}
}
return types.PrintResult(result, conf.CNIVersion)
}

View File

@ -24,7 +24,7 @@ import (
"github.com/containernetworking/cni/pkg/invoke"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"

View File

@ -21,7 +21,8 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/cni/pkg/types/040"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -169,13 +170,14 @@ var _ = Describe("firewall plugin iptables backend", func() {
var originalNS, targetNS ns.NetNS
const IFNAME string = "dummy0"
fullConf := []byte(`{
fullConf := []byte(fmt.Sprintf(`{
"name": "test",
"type": "firewall",
"backend": "iptables",
"ifName": "dummy0",
"cniVersion": "0.3.1",
"cniVersion": "%s",
"prevResult": {
"cniVersion": "%s",
"interfaces": [
{"name": "dummy0"}
],
@ -192,7 +194,7 @@ var _ = Describe("firewall plugin iptables backend", func() {
}
]
}
}`)
}`, current.ImplementedSpecVersion, current.ImplementedSpecVersion))
BeforeEach(func() {
// Create a new NetNS so we don't modify the host
@ -283,14 +285,15 @@ var _ = Describe("firewall plugin iptables backend", func() {
})
It("correctly handles a custom IptablesAdminChainName", func() {
conf := []byte(`{
conf := []byte(fmt.Sprintf(`{
"name": "test",
"type": "firewall",
"backend": "iptables",
"ifName": "dummy0",
"cniVersion": "0.3.1",
"cniVersion": "%s",
"iptablesAdminChainName": "CNI-foobar",
"prevResult": {
"cniVersion": "%s",
"interfaces": [
{"name": "dummy0"}
],
@ -307,7 +310,7 @@ var _ = Describe("firewall plugin iptables backend", func() {
}
]
}
}`)
}`, current.ImplementedSpecVersion, current.ImplementedSpecVersion))
args := &skel.CmdArgs{
ContainerID: "dummy",
@ -434,6 +437,7 @@ var _ = Describe("firewall plugin iptables backend v0.4.x", func() {
"ifName": "dummy0",
"cniVersion": "0.4.0",
"prevResult": {
"cniVersion": "0.4.0",
"interfaces": [
{"name": "dummy0"}
],
@ -498,7 +502,7 @@ var _ = Describe("firewall plugin iptables backend v0.4.x", func() {
})
Expect(err).NotTo(HaveOccurred())
_, err = current.GetResult(r)
_, err = types040.GetResult(r)
Expect(err).NotTo(HaveOccurred())
err = testutils.CmdCheckWithArgs(args, func() error {

View File

@ -18,7 +18,7 @@ import (
"fmt"
"strings"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/godbus/dbus"
)

View File

@ -21,7 +21,7 @@ import (
"fmt"
"net"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/utils"
"github.com/coreos/go-iptables/iptables"
)

View File

@ -189,7 +189,7 @@ func consumeScratchNetConf(containerID, dataDir string) (func(error), []byte, er
return cleanup, netConfBytes, err
}
func delegateAdd(cid, dataDir string, netconf map[string]interface{}) error {
func delegateAdd(cid, dataDir, cniVersion string, netconf map[string]interface{}) error {
netconfBytes, err := json.Marshal(netconf)
if err != nil {
return fmt.Errorf("error serializing delegate netconf: %v", err)
@ -205,7 +205,7 @@ func delegateAdd(cid, dataDir string, netconf map[string]interface{}) error {
return err
}
return result.Print()
return types.PrintResult(result, cniVersion)
}
func hasKey(m map[string]interface{}, k string) bool {
@ -247,7 +247,10 @@ func cmdAdd(args *skel.CmdArgs) error {
n.Delegate["runtimeConfig"] = n.RuntimeConfig
}
return doCmdAdd(args, n, fenv)
// Delegate CNI config version must match flannel plugin config version
n.Delegate["cniVersion"] = n.CNIVersion
return doCmdAdd(args, n.CNIVersion, n, fenv)
}
func cmdDel(args *skel.CmdArgs) error {

View File

@ -72,7 +72,7 @@ func getDelegateIPAM(n *NetConf, fenv *subnetEnv) (map[string]interface{}, error
return ipam, nil
}
func doCmdAdd(args *skel.CmdArgs, n *NetConf, fenv *subnetEnv) error {
func doCmdAdd(args *skel.CmdArgs, cniVersion string, n *NetConf, fenv *subnetEnv) error {
n.Delegate["name"] = n.Name
if !hasKey(n.Delegate, "type") {
@ -105,7 +105,7 @@ func doCmdAdd(args *skel.CmdArgs, n *NetConf, fenv *subnetEnv) error {
}
n.Delegate["ipam"] = ipam
return delegateAdd(args.ContainerID, n.DataDir, n.Delegate)
return delegateAdd(args.ContainerID, n.DataDir, cniVersion, n.Delegate)
}
func doCmdDel(args *skel.CmdArgs, n *NetConf) (err error) {

View File

@ -20,7 +20,7 @@ import (
"os"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -50,12 +50,12 @@ var _ = Describe("Flannel", func() {
Expect(originalNS.Close()).To(Succeed())
})
const inputTemplate = `
{
"name": "cni-flannel",
"type": "flannel",
"subnetFile": "%s",
"dataDir": "%s"%s
const inputTemplate = `{
"name": "cni-flannel",
"type": "flannel",
"cniVersion": "%s",
"subnetFile": "%s",
"dataDir": "%s"%s
}`
const inputIPAMTemplate = `
@ -120,7 +120,7 @@ FLANNEL_IPMASQ=true
ipamPart = ",\n \"ipam\":\n" + inputIPAM
}
return fmt.Sprintf(inputTemplate, subnetFile, dataDir, ipamPart)
return fmt.Sprintf(inputTemplate, current.ImplementedSpecVersion, subnetFile, dataDir, ipamPart)
}
BeforeEach(func() {
@ -176,7 +176,8 @@ FLANNEL_IPMASQ=true
netConfBytes, err := ioutil.ReadFile(path)
Expect(err).NotTo(HaveOccurred())
expected := `{
expected := fmt.Sprintf(`{
"cniVersion": "%s",
"ipMasq": false,
"ipam": {
"routes": [
@ -195,8 +196,7 @@ FLANNEL_IPMASQ=true
"mtu": 1472,
"name": "cni-flannel",
"type": "bridge"
}
`
}`, current.ImplementedSpecVersion)
Expect(netConfBytes).Should(MatchJSON(expected))
result, err := current.NewResultFromResult(resI)
@ -255,7 +255,8 @@ FLANNEL_IPMASQ=true
netConfBytes, err := ioutil.ReadFile(path)
Expect(err).NotTo(HaveOccurred())
expected := `{
expected := fmt.Sprintf(`{
"cniVersion": "%s",
"ipMasq": false,
"ipam": {
"routes": [
@ -274,8 +275,7 @@ FLANNEL_IPMASQ=true
"mtu": 1472,
"name": "cni-flannel",
"type": "bridge"
}
`
}`, current.ImplementedSpecVersion)
Expect(netConfBytes).Should(MatchJSON(expected))
result, err := current.NewResultFromResult(resI)
@ -334,7 +334,8 @@ FLANNEL_IPMASQ=true
netConfBytes, err := ioutil.ReadFile(path)
Expect(err).NotTo(HaveOccurred())
expected := `{
expected := fmt.Sprintf(`{
"cniVersion": "%s",
"ipMasq": false,
"ipam": {
"routes": [
@ -359,8 +360,7 @@ FLANNEL_IPMASQ=true
"mtu": 1472,
"name": "cni-flannel",
"type": "bridge"
}
`
}`, current.ImplementedSpecVersion)
Expect(netConfBytes).Should(MatchJSON(expected))
result, err := current.NewResultFromResult(resI)

View File

@ -30,7 +30,7 @@ import (
"os"
)
func doCmdAdd(args *skel.CmdArgs, n *NetConf, fenv *subnetEnv) error {
func doCmdAdd(args *skel.CmdArgs, cniVersion string, n *NetConf, fenv *subnetEnv) error {
n.Delegate["name"] = n.Name
if !hasKey(n.Delegate, "type") {
@ -52,7 +52,8 @@ func doCmdAdd(args *skel.CmdArgs, n *NetConf, fenv *subnetEnv) error {
"subnet": fenv.sn.String(),
}
return delegateAdd(hns.GetSandboxContainerID(args.ContainerID, args.Netns), n.DataDir, n.Delegate)
sandboxID := hns.GetSandboxContainerID(args.ContainerID, args.Netns)
return delegateAdd(sandboxID, n.DataDir, cniVersion, n.Delegate)
}
func doCmdDel(args *skel.CmdArgs, n *NetConf) (err error) {

View File

@ -33,7 +33,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"golang.org/x/sys/unix"
@ -223,9 +223,10 @@ func parseConfig(stdin []byte, ifName string) (*PortMapConf, *current.Result, er
if conf.PrevResult != nil {
for _, ip := range result.IPs {
if ip.Version == "6" && conf.ContIPv6.IP != nil {
isIPv4 := ip.Address.IP.To4() != nil
if !isIPv4 && conf.ContIPv6.IP != nil {
continue
} else if ip.Version == "4" && conf.ContIPv4.IP != nil {
} else if isIPv4 && conf.ContIPv4.IP != nil {
continue
}
@ -239,11 +240,10 @@ func parseConfig(stdin []byte, ifName string) (*PortMapConf, *current.Result, er
continue
}
}
switch ip.Version {
case "6":
conf.ContIPv6 = ip.Address
case "4":
if ip.Address.IP.To4() != nil {
conf.ContIPv4 = ip.Address
} else {
conf.ContIPv6 = ip.Address
}
}
}

View File

@ -25,7 +25,7 @@ import (
"path/filepath"
"github.com/containernetworking/cni/libcni"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
"github.com/coreos/go-iptables/iptables"

View File

@ -26,7 +26,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ns"
@ -234,7 +234,7 @@ func doRoutes(ipCfgs []*current.IPConfig, origRoutes []*types.Route, iface strin
// Source must be restricted to a single IP, not a full subnet
var src net.IPNet
src.IP = ipCfg.Address.IP
if ipCfg.Version == "4" {
if src.IP.To4() != nil {
src.Mask = net.CIDRMask(32, 32)
} else {
src.Mask = net.CIDRMask(128, 128)
@ -253,7 +253,7 @@ func doRoutes(ipCfgs []*current.IPConfig, origRoutes []*types.Route, iface strin
log.Printf("Adding default route to gateway %s", ipCfg.Gateway.String())
var dest net.IPNet
if ipCfg.Version == "4" {
if ipCfg.Address.IP.To4() != nil {
dest.IP = net.IPv4zero
dest.Mask = net.CIDRMask(0, 32)
} else {

View File

@ -241,6 +241,7 @@ var _ = Describe("sbr test", func() {
"name": "cni-plugin-sbr-test",
"type": "sbr",
"prevResult": {
"cniVersion": "0.3.0",
"interfaces": [
{
"name": "%s",
@ -332,6 +333,7 @@ var _ = Describe("sbr test", func() {
"name": "cni-plugin-sbr-test",
"type": "sbr",
"prevResult": {
"cniVersion": "0.3.0",
"interfaces": [
{
"name": "%s",
@ -399,19 +401,12 @@ var _ = Describe("sbr test", func() {
Expect(equalRoutes(expNet1.Routes, devNet1.Routes)).To(BeTrue())
})
It("works with a 0.2.0 config", func() {
It("fails with CNI spec versions that don't support plugin chaining", func() {
conf := `{
"cniVersion": "0.2.0",
"name": "cni-plugin-sbr-test",
"type": "sbr",
"anotherAwesomeArg": "foo",
"prevResult": {
"ip4": {
"ip": "192.168.1.209/24",
"gateway": "192.168.1.1",
"routes": []
}
}
"anotherAwesomeArg": "foo"
}`
args := &skel.CmdArgs{
@ -424,7 +419,7 @@ var _ = Describe("sbr test", func() {
Expect(err).NotTo(HaveOccurred())
_, _, err = testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
Expect(err).NotTo(HaveOccurred())
Expect(err).To(MatchError("This plugin must be called as chained plugin"))
})
})

View File

@ -32,7 +32,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ns"
@ -322,7 +322,7 @@ func cmdAdd(args *skel.CmdArgs) error {
}
for _, ipc := range result.IPs {
if ipc.Version == "4" {
if ipc.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIfaceByName(ipc.Address.IP, args.IfName)
}
}

View File

@ -21,7 +21,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"

View File

@ -22,7 +22,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
"github.com/containernetworking/plugins/pkg/ns"

View File

@ -20,7 +20,7 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"

View File

@ -19,11 +19,10 @@ package main
import (
"encoding/json"
"fmt"
"net"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
@ -33,21 +32,15 @@ import (
// is passed in on stdin. Your plugin may wish to expose its functionality via
// runtime args, see CONVENTIONS.md in the CNI spec.
type PluginConf struct {
types.NetConf // You may wish to not nest this type
// This embeds the standard NetConf structure which allows your plugin
// to more easily parse standard fields like Name, Type, CNIVersion,
// and PrevResult.
types.NetConf
RuntimeConfig *struct {
SampleConfig map[string]interface{} `json:"sample"`
} `json:"runtimeConfig"`
// This is the previous result, when called in the context of a chained
// plugin. Because this plugin supports multiple versions, we'll have to
// parse this in two passes. If your plugin is not chained, this can be
// removed (though you may wish to error if a non-chainable plugin is
// chained.
// If you need to modify the result before returning it, you will need
// to actually convert it to a concrete versioned struct.
RawPrevResult *map[string]interface{} `json:"prevResult"`
PrevResult *current.Result `json:"-"`
// Add plugin-specifc flags here
MyAwesomeFlag bool `json:"myAwesomeFlag"`
AnotherAwesomeArg string `json:"anotherAwesomeArg"`
@ -61,21 +54,12 @@ func parseConfig(stdin []byte) (*PluginConf, error) {
return nil, fmt.Errorf("failed to parse network configuration: %v", err)
}
// Parse previous result. Remove this if your plugin is not chained.
if conf.RawPrevResult != nil {
resultBytes, err := json.Marshal(conf.RawPrevResult)
if err != nil {
return nil, fmt.Errorf("could not serialize prevResult: %v", err)
}
res, err := version.NewResult(conf.CNIVersion, resultBytes)
if err != nil {
return nil, fmt.Errorf("could not parse prevResult: %v", err)
}
conf.RawPrevResult = nil
conf.PrevResult, err = current.NewResultFromResult(res)
if err != nil {
return nil, fmt.Errorf("could not convert result to current version: %v", err)
}
// Parse previous result. This will parse, validate, and place the
// previous result object into conf.PrevResult. If you need to modify
// or inspect the PrevResult you will need to convert it to a concrete
// versioned Result struct.
if err := version.ParsePrevResult(&conf.NetConf); err != nil {
return nil, fmt.Errorf("could not parse prevResult: %v", err)
}
// End previous result parsing
@ -94,50 +78,62 @@ func cmdAdd(args *skel.CmdArgs) error {
return err
}
// Remove this if this is an "originating" plugin
// A plugin can be either an "originating" plugin or a "chained" plugin.
// Originating plugins perform initial sandbox setup and do not require
// any result from a previous plugin in the chain. A chained plugin
// modifies sandbox configuration that was previously set up by an
// originating plugin and may optionally require a PrevResult from
// earlier plugins in the chain.
// START chained plugin code
if conf.PrevResult == nil {
return fmt.Errorf("must be called as chained plugin")
}
// Uncomment if this is an "originating" plugin
//if conf.PrevResult != nil {
// return fmt.Errorf("must be called as the first plugin")
// }
// This is some sample code to generate the list of container-side IPs.
// We're casting the prevResult to a 0.3.0 response, which can also include
// host-side IPs (but doesn't when converted from a 0.2.0 response).
//
// You don't need this if you are writing an "originating" plugin.
containerIPs := make([]net.IP, 0, len(conf.PrevResult.IPs))
if conf.CNIVersion != "0.3.0" {
for _, ip := range conf.PrevResult.IPs {
containerIPs = append(containerIPs, ip.Address.IP)
}
} else {
for _, ip := range conf.PrevResult.IPs {
if ip.Interface == nil {
continue
}
intIdx := *ip.Interface
// Every IP is indexed in to the interfaces array, with "-1" standing
// for an unknown interface (which we'll assume to be Container-side
// Skip all IPs we know belong to an interface with the wrong name.
if intIdx >= 0 && intIdx < len(conf.PrevResult.Interfaces) && conf.PrevResult.Interfaces[intIdx].Name != args.IfName {
continue
}
containerIPs = append(containerIPs, ip.Address.IP)
}
// Convert the PrevResult to a concrete Result type that can be modified.
prevResult, err := current.GetResult(conf.PrevResult)
if err != nil {
return fmt.Errorf("failed to convert prevResult: %v", err)
}
if len(containerIPs) == 0 {
if len(prevResult.IPs) == 0 {
return fmt.Errorf("got no container IPs")
}
// Pass the prevResult through this plugin to the next one
result := prevResult
// END chained plugin code
// START originating plugin code
// if conf.PrevResult != nil {
// return fmt.Errorf("must be called as the first plugin")
// }
// Generate some fake container IPs and add to the result
// result := &current.Result{CNIVersion: current.ImplementedSpecVersion}
// result.Interfaces = []*current.Interface{
// {
// Name: "intf0",
// Sandbox: args.Netns,
// Mac: "00:11:22:33:44:55",
// },
// }
// result.IPs = []*current.IPConfig{
// {
// Address: "1.2.3.4/24",
// Gateway: "1.2.3.1",
// // Interface is an index into the Interfaces array
// // of the Interface element this IP applies to
// Interface: current.Int(0),
// }
// }
// END originating plugin code
// Implement your plugin here
// Pass through the result for the next plugin
return types.PrintResult(conf.PrevResult, conf.CNIVersion)
return types.PrintResult(result, conf.CNIVersion)
}
// cmdDel is called for DELETE requests

View File

@ -45,6 +45,7 @@ var _ = Describe("sample test", func() {
"type": "sample",
"anotherAwesomeArg": "awesome",
"prevResult": {
"cniVersion": "0.3.0",
"interfaces": [
{
"name": "%s",
@ -71,7 +72,6 @@ var _ = Describe("sample test", func() {
}
_, _, err := testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
Expect(err).NotTo(HaveOccurred())
})
It("fails an invalid config", func() {
@ -106,22 +106,14 @@ var _ = Describe("sample test", func() {
}
_, _, err := testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
Expect(err).To(MatchError("anotherAwesomeArg must be specified"))
})
It("works with a 0.2.0 config", func() {
It("fails with CNI spec versions that don't support plugin chaining", func() {
conf := `{
"cniVersion": "0.2.0",
"name": "cni-plugin-sample-test",
"type": "sample",
"anotherAwesomeArg": "foo",
"prevResult": {
"ip4": {
"ip": "10.0.0.2/24",
"gateway": "10.0.0.1",
"routes": []
}
}
"anotherAwesomeArg": "foo"
}`
args := &skel.CmdArgs{
@ -131,8 +123,7 @@ var _ = Describe("sample test", func() {
StdinData: []byte(conf),
}
_, _, err := testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
Expect(err).NotTo(HaveOccurred())
Expect(err).To(MatchError("must be called as chained plugin"))
})
})