Change:
/kind feature The CNI "capability arguments" parameter - currently used to pass port mappings - has a few new capabilities: bandwidth limiting and network address management. The dockershim's networking driver should use them. The network address is just passing the PodCIDR dynamically to the plugin, so it no longer has to retrieve it from the APIServer. Bandwidth limiting is already implemented in Kubenet. It is configured via annotations. There is no upgrade risk in providing these values; non-compliant plugins will simply ignore them. Administrators need to explicitly enable each capability individually in their CNI configuration file. To avoid skew between runtimes, the other runtimes should also be upgraded to pass these. We may also wish to look in to a way to add this more directly to the CRI, so we don't have this skew problem, but that's a different issue.
/sig network
/assign
fyi.
Looks like this was never done for CRI?
cc

Discussion:
nsenterPath string confDir     string binDirs     []string <ins> podCidr     string </ins> } type cniNetwork struct {

EgressBurst int `json:"egressBurst,omitempty"` } <ins> // cniIpRange maps to the standard CNI ip range Capability type cniIpRange struct { Subnet string `json:"subnet"` } </ins> func SplitDirs(dirs string) []string { // Use comma rather than colon to work better with Windows too return strings.Split(dirs, ",")

continue } <ins> glog.V(4).Infof("Using CNI configuration file %s", confFile) </ins> network := &cniNetwork{ name:          confList.Name, NetworkConfig: confList,

if plugin.getDefaultNetwork() == nil { return errors.New("cni config uninitialized") } <ins> // If the CNI configuration has the ipRanges capability, we need a PodCIDR assigned for _, p := range plugin.getDefaultNetwork().NetworkConfig.Plugins { if p.Network.Capabilities["ipRanges"] { if plugin.podCidr == "" { return errors.New("no PodCIDR set") } break } } </ins> return nil } <ins> // Event handles any change events. The only event ever sent is the PodCIDR change. // No network plugins support changing an already-set PodCIDR func (plugin *cniNetworkPlugin) Event(name string, details map[string]interface{}) { if name != network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE { return } plugin.Lock() defer plugin.Unlock() podCIDR, ok := details[network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR].(string) if !ok { glog.Warningf("%s event didn't contain pod CIDR", network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE) return } if plugin.podCidr != "" { glog.Warningf("Ignoring subsequent pod CIDR update to %s", podCIDR) return } plugin.podCidr = podCIDR } </ins> func (plugin *cniNetworkPlugin) Name() string { return CNIPluginName }

rt.CapabilityArgs["bandwidth"] = bandwidthParam } <ins> // Set the PodCIDR rt.CapabilityArgs["ipRanges"] = [][]cniIpRange{{{Subnet: plugin.podCidr}}} </ins> return rt, nil }

if err != nil { t.Fatalf("Failed to install plugin %s: %v", confFile, err) } <del> networkConfig := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true, "bandwidth": true}  }`, confName, binName) </del> <ins> networkConfig := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true, "bandwidth": true, "ipRanges": true}  }`, confName, binName) </ins> _, err = f.WriteString(networkConfig) if err != nil { t.Fatalf("Failed to write network config file (%v)", err)

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) <ins> // Check that status returns an error if err := cniPlugin.Status(); err == nil { t.Fatalf("cniPlugin returned non-err with no podCidr") } cniPlugin.Event(network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE, map[string]interface{}{ network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR: "10.0.2.0/24", }) if err := cniPlugin.Status(); err != nil { t.Fatalf("unexpected status err: %v", err) } </ins> ports := map[string][]*hostport.PortMapping{ containerID.ID: { {

// Verify the correct network configuration was passed inputConfig := struct { RuntimeConfig struct { <del> Bandwidth    map[string]interface{}   `json:"bandwidth"` PortMappings []map[string]interface{} `json:"portMappings"` </del> <ins> PortMappings []map[string]interface{}   `json:"portMappings"` Bandwidth    map[string]interface{}     `json:"bandwidth"` IpRanges     [][]map[string]interface{} `json:"ipRanges"` </ins> } `json:"runtimeConfig"` }{} inputBytes, inerr := ioutil.ReadFile(inputFile)

t.Errorf("mismatch in expected bandwidth. expected %v got %v", expectedBandwidth, inputConfig.RuntimeConfig.Bandwidth) } <ins> expectedIpRange := [][]map[string]interface{}{ { {"subnet": "10.0.2.0/24"}, }, } if !reflect.DeepEqual(inputConfig.RuntimeConfig.IpRanges, expectedIpRange) { t.Errorf("mismatch in expected ipRange. expected %v got %v", expectedIpRange, inputConfig.RuntimeConfig.IpRanges) } </ins> // Get its IP address status, err := plug.GetPodNetworkStatus("podNamespace", "podName", containerID) if err != nil {