kubelet/networking: add support for cni ConfigLists, pass hostport parameters

** reason for this change **
CNI has recently introduced a new configuration list feature. This
allows for plugin chaining. It also supports varied plugin versions.
This commit is contained in:
Casey Callendrello 2017-04-10 13:18:32 +02:00
parent 8963dd1b8c
commit e4eaad3d24
14 changed files with 258 additions and 43 deletions

View File

@ -36,9 +36,10 @@ go_test(
"//pkg/kubelet/container/testing:go_default_library", "//pkg/kubelet/container/testing:go_default_library",
"//pkg/kubelet/network:go_default_library", "//pkg/kubelet/network:go_default_library",
"//pkg/kubelet/network/cni/testing:go_default_library", "//pkg/kubelet/network/cni/testing:go_default_library",
"//pkg/kubelet/network/hostport:go_default_library",
"//pkg/kubelet/network/testing:go_default_library", "//pkg/kubelet/network/testing:go_default_library",
"//pkg/util/exec:go_default_library", "//pkg/util/exec:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/types:go_default_library", "//vendor/github.com/containernetworking/cni/pkg/types/020:go_default_library",
"//vendor/github.com/stretchr/testify/mock:go_default_library", "//vendor/github.com/stretchr/testify/mock:go_default_library",
"//vendor/k8s.io/client-go/util/testing:go_default_library", "//vendor/k8s.io/client-go/util/testing:go_default_library",
], ],

View File

@ -20,6 +20,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"sort" "sort"
"strings"
"sync" "sync"
"github.com/containernetworking/cni/libcni" "github.com/containernetworking/cni/libcni"
@ -56,10 +57,19 @@ type cniNetworkPlugin struct {
type cniNetwork struct { type cniNetwork struct {
name string name string
NetworkConfig *libcni.NetworkConfig NetworkConfig *libcni.NetworkConfigList
CNIConfig libcni.CNI CNIConfig libcni.CNI
} }
// cniPortMapping maps to the standard CNI portmapping Capability
// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md
type cniPortMapping struct {
HostPort int32 `json:"hostPort"`
ContainerPort int32 `json:"containerPort"`
Protocol string `json:"protocol"`
HostIP string `json:"hostIP"`
}
func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, binDir, vendorCNIDirPrefix string) []network.NetworkPlugin { func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, binDir, vendorCNIDirPrefix string) []network.NetworkPlugin {
if binDir == "" { if binDir == "" {
binDir = DefaultCNIDir binDir = DefaultCNIDir
@ -86,7 +96,7 @@ func getDefaultCNINetwork(pluginDir, binDir, vendorCNIDirPrefix string) (*cniNet
if pluginDir == "" { if pluginDir == "" {
pluginDir = DefaultNetDir pluginDir = DefaultNetDir
} }
files, err := libcni.ConfFiles(pluginDir) files, err := libcni.ConfFiles(pluginDir, []string{".conf", ".conflist", ".json"})
switch { switch {
case err != nil: case err != nil:
return nil, err return nil, err
@ -96,17 +106,37 @@ func getDefaultCNINetwork(pluginDir, binDir, vendorCNIDirPrefix string) (*cniNet
sort.Strings(files) sort.Strings(files)
for _, confFile := range files { for _, confFile := range files {
var confList *libcni.NetworkConfigList
if strings.HasSuffix(confFile, ".conflist") {
confList, err = libcni.ConfListFromFile(confFile)
if err != nil {
glog.Warningf("Error loading CNI config list file %s: %v", confFile, err)
continue
}
} else {
conf, err := libcni.ConfFromFile(confFile) conf, err := libcni.ConfFromFile(confFile)
if err != nil { if err != nil {
glog.Warningf("Error loading CNI config file %s: %v", confFile, err) glog.Warningf("Error loading CNI config file %s: %v", confFile, err)
continue continue
} }
confList, err = libcni.ConfListFromConf(conf)
if err != nil {
glog.Warningf("Error converting CNI config file %s to list: %v", confFile, err)
continue
}
}
if len(confList.Plugins) == 0 {
glog.Warningf("CNI config list %s has no networks, skipping", confFile)
continue
}
confType := confList.Plugins[0].Network.Type
// Search for vendor-specific plugins as well as default plugins in the CNI codebase. // Search for vendor-specific plugins as well as default plugins in the CNI codebase.
vendorDir := vendorCNIDir(vendorCNIDirPrefix, conf.Network.Type) vendorDir := vendorCNIDir(vendorCNIDirPrefix, confType)
cninet := &libcni.CNIConfig{ cninet := &libcni.CNIConfig{
Path: []string{binDir, vendorDir}, Path: []string{binDir, vendorDir},
} }
network := &cniNetwork{name: conf.Network.Name, NetworkConfig: conf, CNIConfig: cninet} network := &cniNetwork{name: confList.Name, NetworkConfig: confList, CNIConfig: cninet}
return network, nil return network, nil
} }
return nil, fmt.Errorf("No valid networks found in %s", pluginDir) return nil, fmt.Errorf("No valid networks found in %s", pluginDir)
@ -117,10 +147,12 @@ func vendorCNIDir(prefix, pluginType string) string {
} }
func getLoNetwork(binDir, vendorDirPrefix string) *cniNetwork { func getLoNetwork(binDir, vendorDirPrefix string) *cniNetwork {
loConfig, err := libcni.ConfFromBytes([]byte(`{ loConfig, err := libcni.ConfListFromBytes([]byte(`{
"cniVersion": "0.1.0", "cniVersion": "0.2.0",
"name": "cni-loopback", "name": "cni-loopback",
"plugins":[{
"type": "loopback" "type": "loopback"
}]
}`)) }`))
if err != nil { if err != nil {
// The hardcoded config above should always be valid and unit tests will // The hardcoded config above should always be valid and unit tests will
@ -128,7 +160,7 @@ func getLoNetwork(binDir, vendorDirPrefix string) *cniNetwork {
panic(err) panic(err)
} }
cninet := &libcni.CNIConfig{ cninet := &libcni.CNIConfig{
Path: []string{vendorCNIDir(vendorDirPrefix, loConfig.Network.Type), binDir}, Path: []string{vendorCNIDir(vendorDirPrefix, "loopback"), binDir},
} }
loNetwork := &cniNetwork{ loNetwork := &cniNetwork{
name: "lo", name: "lo",
@ -200,13 +232,13 @@ func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubec
return fmt.Errorf("CNI failed to retrieve network namespace path: %v", err) return fmt.Errorf("CNI failed to retrieve network namespace path: %v", err)
} }
_, err = plugin.loNetwork.addToNetwork(name, namespace, id, netnsPath) _, err = plugin.addToNetwork(plugin.loNetwork, name, namespace, id, netnsPath)
if err != nil { if err != nil {
glog.Errorf("Error while adding to cni lo network: %s", err) glog.Errorf("Error while adding to cni lo network: %s", err)
return err return err
} }
_, err = plugin.getDefaultNetwork().addToNetwork(name, namespace, id, netnsPath) _, err = plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath)
if err != nil { if err != nil {
glog.Errorf("Error while adding to cni network: %s", err) glog.Errorf("Error while adding to cni network: %s", err)
return err return err
@ -224,7 +256,7 @@ func (plugin *cniNetworkPlugin) TearDownPod(namespace string, name string, id ku
return fmt.Errorf("CNI failed to retrieve network namespace path: %v", err) return fmt.Errorf("CNI failed to retrieve network namespace path: %v", err)
} }
return plugin.getDefaultNetwork().deleteFromNetwork(name, namespace, id, netnsPath) return plugin.deleteFromNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath)
} }
// TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin. // TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin.
@ -243,16 +275,16 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin
return &network.PodNetworkStatus{IP: ip}, nil return &network.PodNetworkStatus{IP: ip}, nil
} }
func (network *cniNetwork) addToNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*cnitypes.Result, error) { func (plugin *cniNetworkPlugin) addToNetwork(network *cniNetwork, podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (cnitypes.Result, error) {
rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath) rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath)
if err != nil { if err != nil {
glog.Errorf("Error adding network when buliding cni runtime conf: %v", err) glog.Errorf("Error adding network when buliding cni runtime conf: %v", err)
return nil, err return nil, err
} }
netconf, cninet := network.NetworkConfig, network.CNIConfig netConf, cniNet := network.NetworkConfig, network.CNIConfig
glog.V(4).Infof("About to run with conf.Network.Type=%v", netconf.Network.Type) glog.V(4).Infof("About to add CNI network %v (type=%v)", netConf.Name, netConf.Plugins[0].Network.Type)
res, err := cninet.AddNetwork(netconf, rt) res, err := cniNet.AddNetworkList(netConf, rt)
if err != nil { if err != nil {
glog.Errorf("Error adding network: %v", err) glog.Errorf("Error adding network: %v", err)
return nil, err return nil, err
@ -261,16 +293,16 @@ func (network *cniNetwork) addToNetwork(podName string, podNamespace string, pod
return res, nil return res, nil
} }
func (network *cniNetwork) deleteFromNetwork(podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) error { func (plugin *cniNetworkPlugin) deleteFromNetwork(network *cniNetwork, podName string, podNamespace string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) error {
rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath) rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath)
if err != nil { if err != nil {
glog.Errorf("Error deleting network when buliding cni runtime conf: %v", err) glog.Errorf("Error deleting network when buliding cni runtime conf: %v", err)
return err return err
} }
netconf, cninet := network.NetworkConfig, network.CNIConfig netConf, cniNet := network.NetworkConfig, network.CNIConfig
glog.V(4).Infof("About to run with conf.Network.Type=%v", netconf.Network.Type) glog.V(4).Infof("About to del CNI network %v (type=%v)", netConf.Name, netConf.Plugins[0].Network.Type)
err = cninet.DelNetwork(netconf, rt) err = cniNet.DelNetworkList(netConf, rt)
if err != nil { if err != nil {
glog.Errorf("Error deleting network: %v", err) glog.Errorf("Error deleting network: %v", err)
return err return err
@ -278,7 +310,7 @@ func (network *cniNetwork) deleteFromNetwork(podName string, podNamespace string
return nil return nil
} }
func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*libcni.RuntimeConf, error) { func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) (*libcni.RuntimeConf, error) {
glog.V(4).Infof("Got netns path %v", podNetnsPath) glog.V(4).Infof("Got netns path %v", podNetnsPath)
glog.V(4).Infof("Using netns path %v", podNs) glog.V(4).Infof("Using netns path %v", podNs)
@ -294,5 +326,24 @@ func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubec
}, },
} }
// port mappings are a cni capability-based args, rather than parameters
// to a specific plugin
portMappings, err := plugin.host.GetPodPortMappings(podInfraContainerID.ID)
if err != nil {
return nil, fmt.Errorf("could not retrieve port mappings: %v", err)
}
portMappingsParam := make([]cniPortMapping, 0, len(portMappings))
for _, p := range portMappings {
portMappingsParam = append(portMappingsParam, cniPortMapping{
HostPort: p.HostPort,
ContainerPort: p.ContainerPort,
Protocol: strings.ToLower(string(p.Protocol)),
HostIP: p.HostIP,
})
}
rt.CapabilityArgs = map[string]interface{}{
"portMappings": portMappingsParam,
}
return rt, nil return rt, nil
} }

View File

@ -20,16 +20,18 @@ package cni
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
"net" "net"
"os" "os"
"path" "path"
"reflect"
"testing" "testing"
"text/template" "text/template"
cnitypes "github.com/containernetworking/cni/pkg/types" types020 "github.com/containernetworking/cni/pkg/types/020"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
utiltesting "k8s.io/client-go/util/testing" utiltesting "k8s.io/client-go/util/testing"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
@ -39,6 +41,7 @@ import (
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
"k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/network"
"k8s.io/kubernetes/pkg/kubelet/network/cni/testing" "k8s.io/kubernetes/pkg/kubelet/network/cni/testing"
"k8s.io/kubernetes/pkg/kubelet/network/hostport"
networktest "k8s.io/kubernetes/pkg/kubelet/network/testing" networktest "k8s.io/kubernetes/pkg/kubelet/network/testing"
utilexec "k8s.io/kubernetes/pkg/util/exec" utilexec "k8s.io/kubernetes/pkg/util/exec"
) )
@ -54,7 +57,7 @@ func installPluginUnderTest(t *testing.T, testVendorCNIDirPrefix, testNetworkCon
if err != nil { if err != nil {
t.Fatalf("Failed to install plugin") t.Fatalf("Failed to install plugin")
} }
networkConfig := fmt.Sprintf("{ \"name\": \"%s\", \"type\": \"%s\" }", plugName, vendorName) networkConfig := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true} }`, plugName, vendorName)
_, err = f.WriteString(networkConfig) _, err = f.WriteString(networkConfig)
if err != nil { if err != nil {
@ -71,7 +74,7 @@ func installPluginUnderTest(t *testing.T, testVendorCNIDirPrefix, testNetworkCon
f, err = os.Create(pluginExec) f, err = os.Create(pluginExec)
const execScriptTempl = `#!/bin/bash const execScriptTempl = `#!/bin/bash
read ignore cat > {{.InputFile}}
env > {{.OutputEnv}} env > {{.OutputEnv}}
echo "%@" >> {{.OutputEnv}} echo "%@" >> {{.OutputEnv}}
export $(echo ${CNI_ARGS} | sed 's/;/ /g') &> /dev/null export $(echo ${CNI_ARGS} | sed 's/;/ /g') &> /dev/null
@ -80,6 +83,7 @@ echo -n "$CNI_COMMAND $CNI_NETNS $K8S_POD_NAMESPACE $K8S_POD_NAME $K8S_POD_INFRA
echo -n "{ \"ip4\": { \"ip\": \"10.1.0.23/24\" } }" echo -n "{ \"ip4\": { \"ip\": \"10.1.0.23/24\" } }"
` `
execTemplateData := &map[string]interface{}{ execTemplateData := &map[string]interface{}{
"InputFile": path.Join(pluginDir, plugName+".in"),
"OutputFile": path.Join(pluginDir, plugName+".out"), "OutputFile": path.Join(pluginDir, plugName+".out"),
"OutputEnv": path.Join(pluginDir, plugName+".env"), "OutputEnv": path.Join(pluginDir, plugName+".env"),
"OutputDir": pluginDir, "OutputDir": pluginDir,
@ -117,10 +121,11 @@ type fakeNetworkHost struct {
runtime kubecontainer.Runtime runtime kubecontainer.Runtime
} }
func NewFakeHost(kubeClient clientset.Interface, pods []*containertest.FakePod) *fakeNetworkHost { func NewFakeHost(kubeClient clientset.Interface, pods []*containertest.FakePod, ports map[string][]*hostport.PortMapping) *fakeNetworkHost {
host := &fakeNetworkHost{ host := &fakeNetworkHost{
kubeClient: kubeClient, networktest.FakePortMappingGetter{PortMaps: ports},
runtime: &containertest.FakeRuntime{ kubeClient,
&containertest.FakeRuntime{
AllPodList: pods, AllPodList: pods,
}, },
} }
@ -207,9 +212,22 @@ func TestCNIPlugin(t *testing.T) {
cniPlugin.execer = fexec cniPlugin.execer = fexec
cniPlugin.loNetwork.CNIConfig = mockLoCNI cniPlugin.loNetwork.CNIConfig = mockLoCNI
mockLoCNI.On("AddNetwork", cniPlugin.loNetwork.NetworkConfig, mock.AnythingOfType("*libcni.RuntimeConf")).Return(&cnitypes.Result{IP4: &cnitypes.IPConfig{IP: net.IPNet{IP: []byte{127, 0, 0, 1}}}}, nil) mockLoCNI.On("AddNetworkList", cniPlugin.loNetwork.NetworkConfig, mock.AnythingOfType("*libcni.RuntimeConf")).Return(&types020.Result{IP4: &types020.IPConfig{IP: net.IPNet{IP: []byte{127, 0, 0, 1}}}}, nil)
plug, err := network.InitNetworkPlugin(plugins, "cni", NewFakeHost(nil, pods), componentconfig.HairpinNone, "10.0.0.0/8", network.UseDefaultMTU) ports := map[string][]*hostport.PortMapping{
containerID.ID: {
{
Name: "name",
HostPort: 8008,
ContainerPort: 80,
Protocol: "UDP",
HostIP: "0.0.0.0",
},
},
}
fakeHost := NewFakeHost(nil, pods, ports)
plug, err := network.InitNetworkPlugin(plugins, "cni", fakeHost, componentconfig.HairpinNone, "10.0.0.0/8", network.UseDefaultMTU)
if err != nil { if err != nil {
t.Fatalf("Failed to select the desired plugin: %v", err) t.Fatalf("Failed to select the desired plugin: %v", err)
} }
@ -223,14 +241,35 @@ func TestCNIPlugin(t *testing.T) {
eo, eerr := ioutil.ReadFile(outputEnv) eo, eerr := ioutil.ReadFile(outputEnv)
outputFile := path.Join(testNetworkConfigPath, pluginName, pluginName+".out") outputFile := path.Join(testNetworkConfigPath, pluginName, pluginName+".out")
output, err := ioutil.ReadFile(outputFile) output, err := ioutil.ReadFile(outputFile)
if err != nil { if err != nil || eerr != nil {
t.Errorf("Failed to read output file %s: %v (env %s err %v)", outputFile, err, eo, eerr) t.Errorf("Failed to read output file %s: %v (env %s err %v)", outputFile, err, eo, eerr)
} }
expectedOutput := "ADD /proc/12345/ns/net podNamespace podName test_infra_container" expectedOutput := "ADD /proc/12345/ns/net podNamespace podName test_infra_container"
if string(output) != expectedOutput { if string(output) != expectedOutput {
t.Errorf("Mismatch in expected output for setup hook. Expected '%s', got '%s'", expectedOutput, string(output)) t.Errorf("Mismatch in expected output for setup hook. Expected '%s', got '%s'", expectedOutput, string(output))
} }
// Verify the correct network configuration was passed
inputConfig := struct {
RuntimeConfig struct {
PortMappings []map[string]interface{} `json:"portMappings"`
} `json:"runtimeConfig"`
}{}
inputFile := path.Join(testNetworkConfigPath, pluginName, pluginName+".in")
inputBytes, inerr := ioutil.ReadFile(inputFile)
parseerr := json.Unmarshal(inputBytes, &inputConfig)
if inerr != nil || parseerr != nil {
t.Errorf("failed to parse reported cni input config %s: (%v %v)", inputFile, inerr, parseerr)
}
expectedMappings := []map[string]interface{}{
// hah, golang always unmarshals unstructured json numbers as float64
{"hostPort": 8008.0, "containerPort": 80.0, "protocol": "udp", "hostIP": "0.0.0.0"},
}
if !reflect.DeepEqual(inputConfig.RuntimeConfig.PortMappings, expectedMappings) {
t.Errorf("mismatch in expected port mappings. expected %v got %v", expectedMappings, inputConfig.RuntimeConfig.PortMappings)
}
// Get its IP address // Get its IP address
status, err := plug.GetPodNetworkStatus("podNamespace", "podName", containerID) status, err := plug.GetPodNetworkStatus("podNamespace", "podName", containerID)
if err != nil { if err != nil {

View File

@ -28,12 +28,22 @@ type MockCNI struct {
mock.Mock mock.Mock
} }
func (m *MockCNI) AddNetwork(net *libcni.NetworkConfig, rt *libcni.RuntimeConf) (*types.Result, error) { func (m *MockCNI) AddNetwork(net *libcni.NetworkConfig, rt *libcni.RuntimeConf) (types.Result, error) {
args := m.Called(net, rt) args := m.Called(net, rt)
return args.Get(0).(*types.Result), args.Error(1) return args.Get(0).(types.Result), args.Error(1)
} }
func (m *MockCNI) DelNetwork(net *libcni.NetworkConfig, rt *libcni.RuntimeConf) error { func (m *MockCNI) DelNetwork(net *libcni.NetworkConfig, rt *libcni.RuntimeConf) error {
args := m.Called(net, rt) args := m.Called(net, rt)
return args.Error(0) return args.Error(0)
} }
func (m *MockCNI) DelNetworkList(net *libcni.NetworkConfigList, rt *libcni.RuntimeConf) error {
args := m.Called(net, rt)
return args.Error(0)
}
func (m *MockCNI) AddNetworkList(net *libcni.NetworkConfigList, rt *libcni.RuntimeConf) (types.Result, error) {
args := m.Called(net, rt)
return args.Get(0).(types.Result), args.Error(1)
}

View File

@ -29,6 +29,7 @@ go_library(
"//pkg/util/sysctl:go_default_library", "//pkg/util/sysctl:go_default_library",
"//vendor/github.com/containernetworking/cni/libcni:go_default_library", "//vendor/github.com/containernetworking/cni/libcni:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/types:go_default_library", "//vendor/github.com/containernetworking/cni/pkg/types:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/types/020:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/vishvananda/netlink:go_default_library", "//vendor/github.com/vishvananda/netlink:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",

View File

@ -31,6 +31,7 @@ import (
"github.com/containernetworking/cni/libcni" "github.com/containernetworking/cni/libcni"
cnitypes "github.com/containernetworking/cni/pkg/types" cnitypes "github.com/containernetworking/cni/pkg/types"
cnitypes020 "github.com/containernetworking/cni/pkg/types/020"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -314,10 +315,15 @@ func (plugin *kubenetNetworkPlugin) setup(namespace string, name string, id kube
} }
// Hook container up with our bridge // Hook container up with our bridge
res, err := plugin.addContainerToNetwork(plugin.netConfig, network.DefaultInterfaceName, namespace, name, id) resT, err := plugin.addContainerToNetwork(plugin.netConfig, network.DefaultInterfaceName, namespace, name, id)
if err != nil { if err != nil {
return err return err
} }
// Coerce the CNI result version
res, err := cnitypes020.GetResult(resT)
if err != nil {
return fmt.Errorf("unable to understand network config: %v", err)
}
if res.IP4 == nil { if res.IP4 == nil {
return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id) return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id)
} }
@ -743,7 +749,7 @@ func (plugin *kubenetNetworkPlugin) buildCNIRuntimeConf(ifName string, id kubeco
}, nil }, nil
} }
func (plugin *kubenetNetworkPlugin) addContainerToNetwork(config *libcni.NetworkConfig, ifName, namespace, name string, id kubecontainer.ContainerID) (*cnitypes.Result, error) { func (plugin *kubenetNetworkPlugin) addContainerToNetwork(config *libcni.NetworkConfig, ifName, namespace, name string, id kubecontainer.ContainerID) (cnitypes.Result, error) {
rt, err := plugin.buildCNIRuntimeConf(ifName, id) rt, err := plugin.buildCNIRuntimeConf(ifName, id)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error building CNI config: %v", err) return nil, fmt.Errorf("Error building CNI config: %v", err)

View File

@ -65,9 +65,9 @@ func (nh *fakeNamespaceGetter) GetNetNS(containerID string) (string, error) {
} }
type FakePortMappingGetter struct { type FakePortMappingGetter struct {
mem map[string][]*hostport.PortMapping PortMaps map[string][]*hostport.PortMapping
} }
func (pm *FakePortMappingGetter) GetPodPortMappings(containerID string) ([]*hostport.PortMapping, error) { func (pm *FakePortMappingGetter) GetPodPortMappings(containerID string) ([]*hostport.PortMapping, error) {
return pm.mem[containerID], nil return pm.PortMaps[containerID], nil
} }

1
vendor/BUILD vendored
View File

@ -63,6 +63,7 @@ filegroup(
"//vendor/github.com/containernetworking/cni/libcni:all-srcs", "//vendor/github.com/containernetworking/cni/libcni:all-srcs",
"//vendor/github.com/containernetworking/cni/pkg/invoke:all-srcs", "//vendor/github.com/containernetworking/cni/pkg/invoke:all-srcs",
"//vendor/github.com/containernetworking/cni/pkg/types:all-srcs", "//vendor/github.com/containernetworking/cni/pkg/types:all-srcs",
"//vendor/github.com/containernetworking/cni/pkg/version:all-srcs",
"//vendor/github.com/coreos/etcd/alarm:all-srcs", "//vendor/github.com/coreos/etcd/alarm:all-srcs",
"//vendor/github.com/coreos/etcd/auth:all-srcs", "//vendor/github.com/coreos/etcd/auth:all-srcs",
"//vendor/github.com/coreos/etcd/client:all-srcs", "//vendor/github.com/coreos/etcd/client:all-srcs",

View File

@ -17,6 +17,7 @@ go_library(
deps = [ deps = [
"//vendor/github.com/containernetworking/cni/pkg/invoke:go_default_library", "//vendor/github.com/containernetworking/cni/pkg/invoke:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/types:go_default_library", "//vendor/github.com/containernetworking/cni/pkg/types:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/version:go_default_library",
], ],
) )

View File

@ -14,9 +14,14 @@ go_library(
"delegate.go", "delegate.go",
"exec.go", "exec.go",
"find.go", "find.go",
"os_unix.go",
"raw_exec.go",
], ],
tags = ["automanaged"], tags = ["automanaged"],
deps = ["//vendor/github.com/containernetworking/cni/pkg/types:go_default_library"], deps = [
"//vendor/github.com/containernetworking/cni/pkg/types:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/version:go_default_library",
],
) )
filegroup( filegroup(

View File

@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["types.go"],
tags = ["automanaged"],
deps = ["//vendor/github.com/containernetworking/cni/pkg/types:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -25,6 +25,10 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//vendor/github.com/containernetworking/cni/pkg/types/020:all-srcs",
"//vendor/github.com/containernetworking/cni/pkg/types/current:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
) )

View File

@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["types.go"],
tags = ["automanaged"],
deps = [
"//vendor/github.com/containernetworking/cni/pkg/types:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/types/020:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"conf.go",
"plugin.go",
"reconcile.go",
"version.go",
],
tags = ["automanaged"],
deps = [
"//vendor/github.com/containernetworking/cni/pkg/types:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/types/020:go_default_library",
"//vendor/github.com/containernetworking/cni/pkg/types/current:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)