Update CNI to v0.6.0
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
01137e4591
commit
af83d3e1f7
@ -1,5 +1,5 @@
|
|||||||
RUNC_VERSION=e775f0fba3ea329b8b766451c892c41a3d49594d
|
RUNC_VERSION=e775f0fba3ea329b8b766451c892c41a3d49594d
|
||||||
CNI_VERSION=v0.4.0
|
CNI_VERSION=v0.6.0
|
||||||
CONTAINERD_VERSION=938810e706bbcdbcb937ce63ba3e7c9ca329af64
|
CONTAINERD_VERSION=938810e706bbcdbcb937ce63ba3e7c9ca329af64
|
||||||
CRITEST_VERSION=74bbd4e142f752f13c648d9dde23defed3e472a2
|
CRITEST_VERSION=74bbd4e142f752f13c648d9dde23defed3e472a2
|
||||||
KUBERNETES_VERSION=493ee8b28560c118cebd2165ba9ef0959cfa2bc3
|
KUBERNETES_VERSION=493ee8b28560c118cebd2165ba9ef0959cfa2bc3
|
||||||
|
49
vendor/github.com/containernetworking/cni/README.md
generated
vendored
49
vendor/github.com/containernetworking/cni/README.md
generated
vendored
@ -2,15 +2,25 @@
|
|||||||
[](https://coveralls.io/github/containernetworking/cni?branch=master)
|
[](https://coveralls.io/github/containernetworking/cni?branch=master)
|
||||||
[](https://cryptic-tundra-43194.herokuapp.com/)
|
[](https://cryptic-tundra-43194.herokuapp.com/)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Community Sync Meeting
|
||||||
|
|
||||||
|
There is a community sync meeting for users and developers every 1-2 months. The next meeting will help on a Google Hangout and the link is in the [agenda](https://docs.google.com/document/d/10ECyT2mBGewsJUcmYmS8QNo1AcNgy2ZIe2xS7lShYhE/edit?usp=sharing) (Notes from previous meeting are also in this doc). The next meeting will be held on *Wednesday, June 21th* at *3:00pm UTC* [Add to Calendar]https://www.worldtimebuddy.com/?qm=1&lid=100,5,2643743,5391959&h=100&date=2017-6-21&sln=15-16).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
# CNI - the Container Network Interface
|
# CNI - the Container Network Interface
|
||||||
|
|
||||||
## What is CNI?
|
## What is CNI?
|
||||||
|
|
||||||
The CNI (_Container Network Interface_) project consists of a specification and libraries for writing plugins to configure network interfaces in Linux containers, along with a number of supported plugins.
|
CNI (_Container Network Interface_), a [Cloud Native Computing Foundation](https://cncf.io) project, consists of a specification and libraries for writing plugins to configure network interfaces in Linux containers, along with a number of supported plugins.
|
||||||
CNI concerns itself only with network connectivity of containers and removing allocated resources when the container is deleted.
|
CNI concerns itself only with network connectivity of containers and removing allocated resources when the container is deleted.
|
||||||
Because of this focus, CNI has a wide range of support and the specification is simple to implement.
|
Because of this focus, CNI has a wide range of support and the specification is simple to implement.
|
||||||
|
|
||||||
As well as the [specification](SPEC.md), this repository contains the Go source code of a library for integrating CNI into applications, an example command-line tool, a template for making new plugins, and the supported plugins.
|
As well as the [specification](SPEC.md), this repository contains the Go source code of a [library for integrating CNI into applications](libcni) and an [example command-line tool](cnitool) for executing CNI plugins. A [separate repository contains reference plugins](https://github.com/containernetworking/plugins) and a template for making new plugins.
|
||||||
|
|
||||||
The template code makes it straight-forward to create a CNI plugin for an existing container networking project.
|
The template code makes it straight-forward to create a CNI plugin for an existing container networking project.
|
||||||
CNI also makes a good framework for creating a new container networking project from scratch.
|
CNI also makes a good framework for creating a new container networking project from scratch.
|
||||||
@ -27,7 +37,8 @@ To avoid duplication, we think it is prudent to define a common interface betwee
|
|||||||
- [rkt - container engine](https://coreos.com/blog/rkt-cni-networking.html)
|
- [rkt - container engine](https://coreos.com/blog/rkt-cni-networking.html)
|
||||||
- [Kurma - container runtime](http://kurma.io/)
|
- [Kurma - container runtime](http://kurma.io/)
|
||||||
- [Kubernetes - a system to simplify container operations](http://kubernetes.io/docs/admin/network-plugins/)
|
- [Kubernetes - a system to simplify container operations](http://kubernetes.io/docs/admin/network-plugins/)
|
||||||
- [Cloud Foundry - a platform for cloud applications](https://github.com/cloudfoundry-incubator/netman-release)
|
- [OpenShift - Kubernetes with additional enterprise features](https://github.com/openshift/origin/blob/master/docs/openshift_networking_requirements.md)
|
||||||
|
- [Cloud Foundry - a platform for cloud applications](https://github.com/cloudfoundry-incubator/cf-networking-release)
|
||||||
- [Mesos - a distributed systems kernel](https://github.com/apache/mesos/blob/master/docs/cni.md)
|
- [Mesos - a distributed systems kernel](https://github.com/apache/mesos/blob/master/docs/cni.md)
|
||||||
|
|
||||||
### 3rd party plugins
|
### 3rd party plugins
|
||||||
@ -37,8 +48,14 @@ To avoid duplication, we think it is prudent to define a common interface betwee
|
|||||||
- [SR-IOV](https://github.com/hustcat/sriov-cni)
|
- [SR-IOV](https://github.com/hustcat/sriov-cni)
|
||||||
- [Cilium - BPF & XDP for containers](https://github.com/cilium/cilium)
|
- [Cilium - BPF & XDP for containers](https://github.com/cilium/cilium)
|
||||||
- [Infoblox - enterprise IP address management for containers](https://github.com/infobloxopen/cni-infoblox)
|
- [Infoblox - enterprise IP address management for containers](https://github.com/infobloxopen/cni-infoblox)
|
||||||
|
- [Multus - a Multi plugin](https://github.com/Intel-Corp/multus-cni)
|
||||||
|
- [Romana - Layer 3 CNI plugin supporting network policy for Kubernetes](https://github.com/romana/kube)
|
||||||
|
- [CNI-Genie - generic CNI network plugin](https://github.com/Huawei-PaaS/CNI-Genie)
|
||||||
|
- [Nuage CNI - Nuage Networks SDN plugin for network policy kubernetes support ](https://github.com/nuagenetworks/nuage-cni)
|
||||||
|
- [Silk - a CNI plugin designed for Cloud Foundry](https://github.com/cloudfoundry-incubator/silk)
|
||||||
|
- [Linen - a CNI plugin designed for overlay networks with Open vSwitch and fit in SDN/OpenFlow network environment](https://github.com/John-Lin/linen-cni)
|
||||||
|
|
||||||
The CNI team also maintains some [core plugins](plugins).
|
The CNI team also maintains some [core plugins in a separate repository](https://github.com/containernetworking/plugins).
|
||||||
|
|
||||||
|
|
||||||
## Contributing to CNI
|
## Contributing to CNI
|
||||||
@ -50,19 +67,16 @@ If you intend to contribute to code or documentation, please read [CONTRIBUTING.
|
|||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
CNI requires Go 1.5+ to build.
|
The CNI spec is language agnostic. To use the Go language libraries in this repository, you'll need a recent version of Go. Our [automated tests](https://travis-ci.org/containernetworking/cni/builds) cover Go versions 1.7 and 1.8.
|
||||||
|
|
||||||
Go 1.5 users will need to set GO15VENDOREXPERIMENT=1 to get vendored
|
### Reference Plugins
|
||||||
dependencies. This flag is set by default in 1.6.
|
|
||||||
|
|
||||||
### Included Plugins
|
The CNI project maintains a set of [reference plugins](https://github.com/containernetworking/plugins) that implement the CNI specification.
|
||||||
|
NOTE: the reference plugins used to live in this repository but have been split out into a [separate repository](https://github.com/containernetworking/plugins) as of May 2017.
|
||||||
This repository includes a number of common plugins in the `plugins/` directory.
|
|
||||||
Please see the [Documentation/](Documentation/) directory for documentation about particular plugins.
|
|
||||||
|
|
||||||
### Running the plugins
|
### Running the plugins
|
||||||
|
|
||||||
The scripts/ directory contains two scripts, `priv-net-run.sh` and `docker-run.sh`, that can be used to exercise the plugins.
|
After building and installing the [reference plugins](https://github.com/containernetworking/plugins), you can use the `priv-net-run.sh` and `docker-run.sh` scripts in the `scripts/` directory to exercise the plugins.
|
||||||
|
|
||||||
**note - priv-net-run.sh depends on `jq`**
|
**note - priv-net-run.sh depends on `jq`**
|
||||||
|
|
||||||
@ -100,14 +114,15 @@ The directory `/etc/cni/net.d` is the default location in which the scripts will
|
|||||||
Next, build the plugins:
|
Next, build the plugins:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ./build
|
$ cd $GOPATH/src/github.com/containernetworking/plugins
|
||||||
|
$ ./build.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, execute a command (`ifconfig` in this example) in a private network namespace that has joined the `mynet` network:
|
Finally, execute a command (`ifconfig` in this example) in a private network namespace that has joined the `mynet` network:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ CNI_PATH=`pwd`/bin
|
$ CNI_PATH=$GOPATH/src/github.com/containernetworking/plugins/bin
|
||||||
$ cd scripts
|
$ cd $GOPATH/src/github.com/containernetworking/cni/scripts
|
||||||
$ sudo CNI_PATH=$CNI_PATH ./priv-net-run.sh ifconfig
|
$ sudo CNI_PATH=$CNI_PATH ./priv-net-run.sh ifconfig
|
||||||
eth0 Link encap:Ethernet HWaddr f2:c2:6f:54:b8:2b
|
eth0 Link encap:Ethernet HWaddr f2:c2:6f:54:b8:2b
|
||||||
inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
|
inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
|
||||||
@ -136,8 +151,8 @@ Use the instructions in the previous section to define a netconf and build the p
|
|||||||
Next, docker-run.sh script wraps `docker run`, to execute the plugins prior to entering the container:
|
Next, docker-run.sh script wraps `docker run`, to execute the plugins prior to entering the container:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ CNI_PATH=`pwd`/bin
|
$ CNI_PATH=$GOPATH/src/github.com/containernetworking/plugins/bin
|
||||||
$ cd scripts
|
$ cd $GOPATH/src/github.com/containernetworking/cni/scripts
|
||||||
$ sudo CNI_PATH=$CNI_PATH ./docker-run.sh --rm busybox:latest ifconfig
|
$ sudo CNI_PATH=$CNI_PATH ./docker-run.sh --rm busybox:latest ifconfig
|
||||||
eth0 Link encap:Ethernet HWaddr fa:60:70:aa:07:d1
|
eth0 Link encap:Ethernet HWaddr fa:60:70:aa:07:d1
|
||||||
inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
|
inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
|
||||||
|
137
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
137
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
@ -15,6 +15,7 @@
|
|||||||
package libcni
|
package libcni
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/invoke"
|
"github.com/containernetworking/cni/pkg/invoke"
|
||||||
@ -27,6 +28,12 @@ type RuntimeConf struct {
|
|||||||
NetNS string
|
NetNS string
|
||||||
IfName string
|
IfName string
|
||||||
Args [][2]string
|
Args [][2]string
|
||||||
|
// A dictionary of capability-specific data passed by the runtime
|
||||||
|
// to plugins as top-level keys in the 'runtimeConfig' dictionary
|
||||||
|
// of the plugin's stdin data. libcni will ensure that only keys
|
||||||
|
// in this map which match the capabilities of the plugin are passed
|
||||||
|
// to the plugin
|
||||||
|
CapabilityArgs map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkConfig struct {
|
type NetworkConfig struct {
|
||||||
@ -34,8 +41,18 @@ type NetworkConfig struct {
|
|||||||
Bytes []byte
|
Bytes []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NetworkConfigList struct {
|
||||||
|
Name string
|
||||||
|
CNIVersion string
|
||||||
|
Plugins []*NetworkConfig
|
||||||
|
Bytes []byte
|
||||||
|
}
|
||||||
|
|
||||||
type CNI interface {
|
type CNI interface {
|
||||||
AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*types.Result, error)
|
AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
|
||||||
|
DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error
|
||||||
|
|
||||||
|
AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
||||||
DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
|
DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,13 +63,120 @@ type CNIConfig struct {
|
|||||||
// CNIConfig implements the CNI interface
|
// CNIConfig implements the CNI interface
|
||||||
var _ CNI = &CNIConfig{}
|
var _ CNI = &CNIConfig{}
|
||||||
|
|
||||||
// AddNetwork executes the plugin with the ADD command
|
func buildOneConfig(list *NetworkConfigList, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, error) {
|
||||||
func (c *CNIConfig) AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*types.Result, error) {
|
var err error
|
||||||
|
|
||||||
|
inject := map[string]interface{}{
|
||||||
|
"name": list.Name,
|
||||||
|
"cniVersion": list.CNIVersion,
|
||||||
|
}
|
||||||
|
// Add previous plugin result
|
||||||
|
if prevResult != nil {
|
||||||
|
inject["prevResult"] = prevResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure every config uses the same name and version
|
||||||
|
orig, err = InjectConf(orig, inject)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return injectRuntimeConfig(orig, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function takes a libcni RuntimeConf structure and injects values into
|
||||||
|
// a "runtimeConfig" dictionary in the CNI network configuration JSON that
|
||||||
|
// will be passed to the plugin on stdin.
|
||||||
|
//
|
||||||
|
// Only "capabilities arguments" passed by the runtime are currently injected.
|
||||||
|
// These capabilities arguments are filtered through the plugin's advertised
|
||||||
|
// capabilities from its config JSON, and any keys in the CapabilityArgs
|
||||||
|
// matching plugin capabilities are added to the "runtimeConfig" dictionary
|
||||||
|
// sent to the plugin via JSON on stdin. For exmaple, if the plugin's
|
||||||
|
// capabilities include "portMappings", and the CapabilityArgs map includes a
|
||||||
|
// "portMappings" key, that key and its value are added to the "runtimeConfig"
|
||||||
|
// dictionary to be passed to the plugin's stdin.
|
||||||
|
func injectRuntimeConfig(orig *NetworkConfig, rt *RuntimeConf) (*NetworkConfig, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
rc := make(map[string]interface{})
|
||||||
|
for capability, supported := range orig.Network.Capabilities {
|
||||||
|
if !supported {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if data, ok := rt.CapabilityArgs[capability]; ok {
|
||||||
|
rc[capability] = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(rc) > 0 {
|
||||||
|
orig, err = InjectConf(orig, map[string]interface{}{"runtimeConfig": rc})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return orig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNetworkList executes a sequence of plugins with the ADD command
|
||||||
|
func (c *CNIConfig) AddNetworkList(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) {
|
||||||
|
var prevResult types.Result
|
||||||
|
for _, net := range list.Plugins {
|
||||||
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newConf, err := buildOneConfig(list, net, prevResult, rt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
prevResult, err = invoke.ExecPluginWithResult(pluginPath, newConf.Bytes, c.args("ADD", rt))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prevResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelNetworkList executes a sequence of plugins with the DEL command
|
||||||
|
func (c *CNIConfig) DelNetworkList(list *NetworkConfigList, rt *RuntimeConf) error {
|
||||||
|
for i := len(list.Plugins) - 1; i >= 0; i-- {
|
||||||
|
net := list.Plugins[i]
|
||||||
|
|
||||||
|
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newConf, err := buildOneConfig(list, net, nil, rt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := invoke.ExecPluginWithoutResult(pluginPath, newConf.Bytes, c.args("DEL", rt)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNetwork executes the plugin with the ADD command
|
||||||
|
func (c *CNIConfig) AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
|
||||||
|
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
net, err = injectRuntimeConfig(net, rt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return invoke.ExecPluginWithResult(pluginPath, net.Bytes, c.args("ADD", rt))
|
return invoke.ExecPluginWithResult(pluginPath, net.Bytes, c.args("ADD", rt))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +187,11 @@ func (c *CNIConfig) DelNetwork(net *NetworkConfig, rt *RuntimeConf) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net, err = injectRuntimeConfig(net, rt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return invoke.ExecPluginWithoutResult(pluginPath, net.Bytes, c.args("DEL", rt))
|
return invoke.ExecPluginWithoutResult(pluginPath, net.Bytes, c.args("DEL", rt))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +214,6 @@ func (c *CNIConfig) args(action string, rt *RuntimeConf) *invoke.Args {
|
|||||||
NetNS: rt.NetNS,
|
NetNS: rt.NetNS,
|
||||||
PluginArgs: rt.Args,
|
PluginArgs: rt.Args,
|
||||||
IfName: rt.IfName,
|
IfName: rt.IfName,
|
||||||
Path: strings.Join(c.Path, ":"),
|
Path: strings.Join(c.Path, string(os.PathListSeparator)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
165
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
165
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
@ -23,6 +23,23 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type NotFoundError struct {
|
||||||
|
Dir string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e NotFoundError) Error() string {
|
||||||
|
return fmt.Sprintf(`no net configuration with name "%s" in %s`, e.Name, e.Dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NoConfigsFoundError struct {
|
||||||
|
Dir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e NoConfigsFoundError) Error() string {
|
||||||
|
return fmt.Sprintf(`no net configurations found in %s`, e.Dir)
|
||||||
|
}
|
||||||
|
|
||||||
func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
|
func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
|
||||||
conf := &NetworkConfig{Bytes: bytes}
|
conf := &NetworkConfig{Bytes: bytes}
|
||||||
if err := json.Unmarshal(bytes, &conf.Network); err != nil {
|
if err := json.Unmarshal(bytes, &conf.Network); err != nil {
|
||||||
@ -39,7 +56,73 @@ func ConfFromFile(filename string) (*NetworkConfig, error) {
|
|||||||
return ConfFromBytes(bytes)
|
return ConfFromBytes(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConfFiles(dir string) ([]string, error) {
|
func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
|
||||||
|
rawList := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal(bytes, &rawList); err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing configuration list: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rawName, ok := rawList["name"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error parsing configuration list: no name")
|
||||||
|
}
|
||||||
|
name, ok := rawName.(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error parsing configuration list: invalid name type %T", rawName)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cniVersion string
|
||||||
|
rawVersion, ok := rawList["cniVersion"]
|
||||||
|
if ok {
|
||||||
|
cniVersion, ok = rawVersion.(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error parsing configuration list: invalid cniVersion type %T", rawVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list := &NetworkConfigList{
|
||||||
|
Name: name,
|
||||||
|
CNIVersion: cniVersion,
|
||||||
|
Bytes: bytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
var plugins []interface{}
|
||||||
|
plug, ok := rawList["plugins"]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error parsing configuration list: no 'plugins' key")
|
||||||
|
}
|
||||||
|
plugins, ok = plug.([]interface{})
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error parsing configuration list: invalid 'plugins' type %T", plug)
|
||||||
|
}
|
||||||
|
if len(plugins) == 0 {
|
||||||
|
return nil, fmt.Errorf("error parsing configuration list: no plugins in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, conf := range plugins {
|
||||||
|
newBytes, err := json.Marshal(conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to marshal plugin config %d: %v", i, err)
|
||||||
|
}
|
||||||
|
netConf, err := ConfFromBytes(newBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to parse plugin config %d: %v", i, err)
|
||||||
|
}
|
||||||
|
list.Plugins = append(list.Plugins, netConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfListFromFile(filename string) (*NetworkConfigList, error) {
|
||||||
|
bytes, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error reading %s: %s", filename, err)
|
||||||
|
}
|
||||||
|
return ConfListFromBytes(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfFiles(dir string, extensions []string) ([]string, error) {
|
||||||
// In part, adapted from rkt/networking/podenv.go#listFiles
|
// In part, adapted from rkt/networking/podenv.go#listFiles
|
||||||
files, err := ioutil.ReadDir(dir)
|
files, err := ioutil.ReadDir(dir)
|
||||||
switch {
|
switch {
|
||||||
@ -56,20 +139,22 @@ func ConfFiles(dir string) ([]string, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fileExt := filepath.Ext(f.Name())
|
fileExt := filepath.Ext(f.Name())
|
||||||
if fileExt == ".conf" || fileExt == ".json" {
|
for _, ext := range extensions {
|
||||||
|
if fileExt == ext {
|
||||||
confFiles = append(confFiles, filepath.Join(dir, f.Name()))
|
confFiles = append(confFiles, filepath.Join(dir, f.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return confFiles, nil
|
return confFiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConf(dir, name string) (*NetworkConfig, error) {
|
func LoadConf(dir, name string) (*NetworkConfig, error) {
|
||||||
files, err := ConfFiles(dir)
|
files, err := ConfFiles(dir, []string{".conf", ".json"})
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return nil, err
|
return nil, err
|
||||||
case len(files) == 0:
|
case len(files) == 0:
|
||||||
return nil, fmt.Errorf("no net configurations found")
|
return nil, NoConfigsFoundError{Dir: dir}
|
||||||
}
|
}
|
||||||
sort.Strings(files)
|
sort.Strings(files)
|
||||||
|
|
||||||
@ -82,25 +167,59 @@ func LoadConf(dir, name string) (*NetworkConfig, error) {
|
|||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf(`no net configuration with name "%s" in %s`, name, dir)
|
return nil, NotFoundError{dir, name}
|
||||||
}
|
}
|
||||||
|
|
||||||
func InjectConf(original *NetworkConfig, key string, newValue interface{}) (*NetworkConfig, error) {
|
func LoadConfList(dir, name string) (*NetworkConfigList, error) {
|
||||||
|
files, err := ConfFiles(dir, []string{".conflist"})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sort.Strings(files)
|
||||||
|
|
||||||
|
for _, confFile := range files {
|
||||||
|
conf, err := ConfListFromFile(confFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if conf.Name == name {
|
||||||
|
return conf, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try and load a network configuration file (instead of list)
|
||||||
|
// from the same name, then upconvert.
|
||||||
|
singleConf, err := LoadConf(dir, name)
|
||||||
|
if err != nil {
|
||||||
|
// A little extra logic so the error makes sense
|
||||||
|
if _, ok := err.(NoConfigsFoundError); len(files) != 0 && ok {
|
||||||
|
// Config lists found but no config files found
|
||||||
|
return nil, NotFoundError{dir, name}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ConfListFromConf(singleConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InjectConf(original *NetworkConfig, newValues map[string]interface{}) (*NetworkConfig, error) {
|
||||||
config := make(map[string]interface{})
|
config := make(map[string]interface{})
|
||||||
err := json.Unmarshal(original.Bytes, &config)
|
err := json.Unmarshal(original.Bytes, &config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unmarshal existing network bytes: %s", err)
|
return nil, fmt.Errorf("unmarshal existing network bytes: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for key, value := range newValues {
|
||||||
if key == "" {
|
if key == "" {
|
||||||
return nil, fmt.Errorf("key value can not be empty")
|
return nil, fmt.Errorf("keys cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
if newValue == nil {
|
if value == nil {
|
||||||
return nil, fmt.Errorf("newValue must be specified")
|
return nil, fmt.Errorf("key '%s' value must not be nil", key)
|
||||||
}
|
}
|
||||||
|
|
||||||
config[key] = newValue
|
config[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
newBytes, err := json.Marshal(config)
|
newBytes, err := json.Marshal(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -109,3 +228,29 @@ func InjectConf(original *NetworkConfig, key string, newValue interface{}) (*Net
|
|||||||
|
|
||||||
return ConfFromBytes(newBytes)
|
return ConfFromBytes(newBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfListFromConf "upconverts" a network config in to a NetworkConfigList,
|
||||||
|
// with the single network as the only entry in the list.
|
||||||
|
func ConfListFromConf(original *NetworkConfig) (*NetworkConfigList, error) {
|
||||||
|
// Re-deserialize the config's json, then make a raw map configlist.
|
||||||
|
// This may seem a bit strange, but it's to make the Bytes fields
|
||||||
|
// actually make sense. Otherwise, the generated json is littered with
|
||||||
|
// golang default values.
|
||||||
|
|
||||||
|
rawConfig := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal(original.Bytes, &rawConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rawConfigList := map[string]interface{}{
|
||||||
|
"name": original.Network.Name,
|
||||||
|
"cniVersion": original.Network.CNIVersion,
|
||||||
|
"plugins": []interface{}{rawConfig},
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(rawConfigList)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ConfListFromBytes(b)
|
||||||
|
}
|
||||||
|
17
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
17
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
@ -57,13 +57,16 @@ func (args *Args) AsEnv() []string {
|
|||||||
pluginArgsStr = stringify(args.PluginArgs)
|
pluginArgsStr = stringify(args.PluginArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
env = append(env,
|
// Ensure that the custom values are first, so any value present in
|
||||||
"CNI_COMMAND="+args.Command,
|
// the process environment won't override them.
|
||||||
"CNI_CONTAINERID="+args.ContainerID,
|
env = append([]string{
|
||||||
"CNI_NETNS="+args.NetNS,
|
"CNI_COMMAND=" + args.Command,
|
||||||
"CNI_ARGS="+pluginArgsStr,
|
"CNI_CONTAINERID=" + args.ContainerID,
|
||||||
"CNI_IFNAME="+args.IfName,
|
"CNI_NETNS=" + args.NetNS,
|
||||||
"CNI_PATH="+args.Path)
|
"CNI_ARGS=" + pluginArgsStr,
|
||||||
|
"CNI_IFNAME=" + args.IfName,
|
||||||
|
"CNI_PATH=" + args.Path,
|
||||||
|
}, env...)
|
||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
generated
vendored
8
vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
generated
vendored
@ -17,17 +17,17 @@ package invoke
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DelegateAdd(delegatePlugin string, netconf []byte) (*types.Result, error) {
|
func DelegateAdd(delegatePlugin string, netconf []byte) (types.Result, error) {
|
||||||
if os.Getenv("CNI_COMMAND") != "ADD" {
|
if os.Getenv("CNI_COMMAND") != "ADD" {
|
||||||
return nil, fmt.Errorf("CNI_COMMAND is not ADD")
|
return nil, fmt.Errorf("CNI_COMMAND is not ADD")
|
||||||
}
|
}
|
||||||
|
|
||||||
paths := strings.Split(os.Getenv("CNI_PATH"), ":")
|
paths := filepath.SplitList(os.Getenv("CNI_PATH"))
|
||||||
|
|
||||||
pluginPath, err := FindInPath(delegatePlugin, paths)
|
pluginPath, err := FindInPath(delegatePlugin, paths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -42,7 +42,7 @@ func DelegateDel(delegatePlugin string, netconf []byte) error {
|
|||||||
return fmt.Errorf("CNI_COMMAND is not DEL")
|
return fmt.Errorf("CNI_COMMAND is not DEL")
|
||||||
}
|
}
|
||||||
|
|
||||||
paths := strings.Split(os.Getenv("CNI_PATH"), ":")
|
paths := filepath.SplitList(os.Getenv("CNI_PATH"))
|
||||||
|
|
||||||
pluginPath, err := FindInPath(delegatePlugin, paths)
|
pluginPath, err := FindInPath(delegatePlugin, paths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
16
vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
generated
vendored
16
vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
generated
vendored
@ -15,7 +15,6 @@
|
|||||||
package invoke
|
package invoke
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -23,7 +22,7 @@ import (
|
|||||||
"github.com/containernetworking/cni/pkg/version"
|
"github.com/containernetworking/cni/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs) (*types.Result, error) {
|
func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error) {
|
||||||
return defaultPluginExec.WithResult(pluginPath, netconf, args)
|
return defaultPluginExec.WithResult(pluginPath, netconf, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,15 +48,20 @@ type PluginExec struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PluginExec) WithResult(pluginPath string, netconf []byte, args CNIArgs) (*types.Result, error) {
|
func (e *PluginExec) WithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error) {
|
||||||
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv())
|
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := &types.Result{}
|
// Plugin must return result in same version as specified in netconf
|
||||||
err = json.Unmarshal(stdoutBytes, res)
|
versionDecoder := &version.ConfigDecoder{}
|
||||||
return res, err
|
confVersion, err := versionDecoder.Decode(netconf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return version.NewResult(confVersion, stdoutBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *PluginExec) WithoutResult(pluginPath string, netconf []byte, args CNIArgs) error {
|
func (e *PluginExec) WithoutResult(pluginPath string, netconf []byte, args CNIArgs) error {
|
||||||
|
20
vendor/github.com/containernetworking/cni/pkg/invoke/find.go
generated
vendored
20
vendor/github.com/containernetworking/cni/pkg/invoke/find.go
generated
vendored
@ -30,18 +30,14 @@ func FindInPath(plugin string, paths []string) (string, error) {
|
|||||||
return "", fmt.Errorf("no paths provided")
|
return "", fmt.Errorf("no paths provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullpath string
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
full := filepath.Join(path, plugin)
|
for _, fe := range ExecutableFileExtensions {
|
||||||
if fi, err := os.Stat(full); err == nil && fi.Mode().IsRegular() {
|
fullpath := filepath.Join(path, plugin) + fe
|
||||||
fullpath = full
|
if fi, err := os.Stat(fullpath); err == nil && fi.Mode().IsRegular() {
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if fullpath == "" {
|
|
||||||
return "", fmt.Errorf("failed to find plugin %q in path %s", plugin, paths)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fullpath, nil
|
return fullpath, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("failed to find plugin %q in path %s", plugin, paths)
|
||||||
}
|
}
|
||||||
|
20
vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
generated
vendored
Normal file
20
vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2016 CNI authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd opensbd solaris
|
||||||
|
|
||||||
|
package invoke
|
||||||
|
|
||||||
|
// Valid file extensions for plugin executables.
|
||||||
|
var ExecutableFileExtensions = []string{""}
|
18
vendor/github.com/containernetworking/cni/pkg/invoke/os_windows.go
generated
vendored
Normal file
18
vendor/github.com/containernetworking/cni/pkg/invoke/os_windows.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2016 CNI authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package invoke
|
||||||
|
|
||||||
|
// Valid file extensions for plugin executables.
|
||||||
|
var ExecutableFileExtensions = []string{".exe", ""}
|
8
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
8
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
@ -50,13 +50,9 @@ func pluginErr(err error, output []byte) error {
|
|||||||
if _, ok := err.(*exec.ExitError); ok {
|
if _, ok := err.(*exec.ExitError); ok {
|
||||||
emsg := types.Error{}
|
emsg := types.Error{}
|
||||||
if perr := json.Unmarshal(output, &emsg); perr != nil {
|
if perr := json.Unmarshal(output, &emsg); perr != nil {
|
||||||
return fmt.Errorf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr)
|
emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr)
|
||||||
}
|
}
|
||||||
details := ""
|
return &emsg
|
||||||
if emsg.Details != "" {
|
|
||||||
details = fmt.Sprintf("; %v", emsg.Details)
|
|
||||||
}
|
|
||||||
return fmt.Errorf("%v%v", emsg.Msg, details)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
135
vendor/github.com/containernetworking/cni/pkg/types/020/types.go
generated
vendored
Normal file
135
vendor/github.com/containernetworking/cni/pkg/types/020/types.go
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
// Copyright 2016 CNI authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package types020
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ImplementedSpecVersion string = "0.2.0"
|
||||||
|
|
||||||
|
var SupportedVersions = []string{"", "0.1.0", ImplementedSpecVersion}
|
||||||
|
|
||||||
|
// Compatibility types for CNI version 0.1.0 and 0.2.0
|
||||||
|
|
||||||
|
func NewResult(data []byte) (types.Result, error) {
|
||||||
|
result := &Result{}
|
||||||
|
if err := json.Unmarshal(data, result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetResult(r types.Result) (*Result, error) {
|
||||||
|
// We expect version 0.1.0/0.2.0 results
|
||||||
|
result020, err := r.GetAsVersion(ImplementedSpecVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result, ok := result020.(*Result)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("failed to convert result")
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result is what gets returned from the plugin (via stdout) to the caller
|
||||||
|
type Result struct {
|
||||||
|
CNIVersion string `json:"cniVersion,omitempty"`
|
||||||
|
IP4 *IPConfig `json:"ip4,omitempty"`
|
||||||
|
IP6 *IPConfig `json:"ip6,omitempty"`
|
||||||
|
DNS types.DNS `json:"dns,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) Version() string {
|
||||||
|
return ImplementedSpecVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) GetAsVersion(version string) (types.Result, error) {
|
||||||
|
for _, supportedVersion := range SupportedVersions {
|
||||||
|
if version == supportedVersion {
|
||||||
|
r.CNIVersion = version
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("cannot convert version %q to %s", SupportedVersions, version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) Print() error {
|
||||||
|
data, err := json.MarshalIndent(r, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = os.Stdout.Write(data)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a formatted string in the form of "[IP4: $1,][ IP6: $2,] DNS: $3" where
|
||||||
|
// $1 represents the receiver's IPv4, $2 represents the receiver's IPv6 and $3 the
|
||||||
|
// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
|
||||||
|
func (r *Result) String() string {
|
||||||
|
var str string
|
||||||
|
if r.IP4 != nil {
|
||||||
|
str = fmt.Sprintf("IP4:%+v, ", *r.IP4)
|
||||||
|
}
|
||||||
|
if r.IP6 != nil {
|
||||||
|
str += fmt.Sprintf("IP6:%+v, ", *r.IP6)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPConfig contains values necessary to configure an interface
|
||||||
|
type IPConfig struct {
|
||||||
|
IP net.IPNet
|
||||||
|
Gateway net.IP
|
||||||
|
Routes []types.Route
|
||||||
|
}
|
||||||
|
|
||||||
|
// net.IPNet is not JSON (un)marshallable so this duality is needed
|
||||||
|
// for our custom IPNet type
|
||||||
|
|
||||||
|
// JSON (un)marshallable types
|
||||||
|
type ipConfig struct {
|
||||||
|
IP types.IPNet `json:"ip"`
|
||||||
|
Gateway net.IP `json:"gateway,omitempty"`
|
||||||
|
Routes []types.Route `json:"routes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *IPConfig) MarshalJSON() ([]byte, error) {
|
||||||
|
ipc := ipConfig{
|
||||||
|
IP: types.IPNet(c.IP),
|
||||||
|
Gateway: c.Gateway,
|
||||||
|
Routes: c.Routes,
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(ipc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *IPConfig) UnmarshalJSON(data []byte) error {
|
||||||
|
ipc := ipConfig{}
|
||||||
|
if err := json.Unmarshal(data, &ipc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.IP = net.IPNet(ipc.IP)
|
||||||
|
c.Gateway = ipc.Gateway
|
||||||
|
c.Routes = ipc.Routes
|
||||||
|
return nil
|
||||||
|
}
|
15
vendor/github.com/containernetworking/cni/pkg/types/args.go
generated
vendored
15
vendor/github.com/containernetworking/cni/pkg/types/args.go
generated
vendored
@ -63,6 +63,12 @@ func GetKeyField(keyString string, v reflect.Value) reflect.Value {
|
|||||||
return v.Elem().FieldByName(keyString)
|
return v.Elem().FieldByName(keyString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalableArgsError is used to indicate error unmarshalling args
|
||||||
|
// from the args-string in the form "K=V;K2=V2;..."
|
||||||
|
type UnmarshalableArgsError struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
// LoadArgs parses args from a string in the form "K=V;K2=V2;..."
|
// LoadArgs parses args from a string in the form "K=V;K2=V2;..."
|
||||||
func LoadArgs(args string, container interface{}) error {
|
func LoadArgs(args string, container interface{}) error {
|
||||||
if args == "" {
|
if args == "" {
|
||||||
@ -85,8 +91,13 @@ func LoadArgs(args string, container interface{}) error {
|
|||||||
unknownArgs = append(unknownArgs, pair)
|
unknownArgs = append(unknownArgs, pair)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
keyFieldIface := keyField.Addr().Interface()
|
||||||
u := keyField.Addr().Interface().(encoding.TextUnmarshaler)
|
u, ok := keyFieldIface.(encoding.TextUnmarshaler)
|
||||||
|
if !ok {
|
||||||
|
return UnmarshalableArgsError{fmt.Errorf(
|
||||||
|
"ARGS: cannot unmarshal into field '%s' - type '%s' does not implement encoding.TextUnmarshaler",
|
||||||
|
keyString, reflect.TypeOf(keyFieldIface))}
|
||||||
|
}
|
||||||
err := u.UnmarshalText([]byte(valueString))
|
err := u.UnmarshalText([]byte(valueString))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ARGS: error parsing value of pair %q: %v)", pair, err)
|
return fmt.Errorf("ARGS: error parsing value of pair %q: %v)", pair, err)
|
||||||
|
300
vendor/github.com/containernetworking/cni/pkg/types/current/types.go
generated
vendored
Normal file
300
vendor/github.com/containernetworking/cni/pkg/types/current/types.go
generated
vendored
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
// Copyright 2016 CNI authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package current
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
|
"github.com/containernetworking/cni/pkg/types/020"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ImplementedSpecVersion string = "0.3.1"
|
||||||
|
|
||||||
|
var SupportedVersions = []string{"0.3.0", ImplementedSpecVersion}
|
||||||
|
|
||||||
|
func NewResult(data []byte) (types.Result, error) {
|
||||||
|
result := &Result{}
|
||||||
|
if err := json.Unmarshal(data, result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetResult(r types.Result) (*Result, error) {
|
||||||
|
resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result, ok := resultCurrent.(*Result)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("failed to convert result")
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultConverters = []struct {
|
||||||
|
versions []string
|
||||||
|
convert func(types.Result) (*Result, error)
|
||||||
|
}{
|
||||||
|
{types020.SupportedVersions, convertFrom020},
|
||||||
|
{SupportedVersions, convertFrom030},
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertFrom020(result types.Result) (*Result, error) {
|
||||||
|
oldResult, err := types020.GetResult(result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newResult := &Result{
|
||||||
|
CNIVersion: ImplementedSpecVersion,
|
||||||
|
DNS: oldResult.DNS,
|
||||||
|
Routes: []*types.Route{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldResult.IP4 != nil {
|
||||||
|
newResult.IPs = append(newResult.IPs, &IPConfig{
|
||||||
|
Version: "4",
|
||||||
|
Address: oldResult.IP4.IP,
|
||||||
|
Gateway: oldResult.IP4.Gateway,
|
||||||
|
})
|
||||||
|
for _, route := range oldResult.IP4.Routes {
|
||||||
|
gw := route.GW
|
||||||
|
if gw == nil {
|
||||||
|
gw = oldResult.IP4.Gateway
|
||||||
|
}
|
||||||
|
newResult.Routes = append(newResult.Routes, &types.Route{
|
||||||
|
Dst: route.Dst,
|
||||||
|
GW: gw,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldResult.IP6 != nil {
|
||||||
|
newResult.IPs = append(newResult.IPs, &IPConfig{
|
||||||
|
Version: "6",
|
||||||
|
Address: oldResult.IP6.IP,
|
||||||
|
Gateway: oldResult.IP6.Gateway,
|
||||||
|
})
|
||||||
|
for _, route := range oldResult.IP6.Routes {
|
||||||
|
gw := route.GW
|
||||||
|
if gw == nil {
|
||||||
|
gw = oldResult.IP6.Gateway
|
||||||
|
}
|
||||||
|
newResult.Routes = append(newResult.Routes, &types.Route{
|
||||||
|
Dst: route.Dst,
|
||||||
|
GW: gw,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(newResult.IPs) == 0 {
|
||||||
|
return nil, fmt.Errorf("cannot convert: no valid IP addresses")
|
||||||
|
}
|
||||||
|
|
||||||
|
return newResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertFrom030(result types.Result) (*Result, error) {
|
||||||
|
newResult, ok := result.(*Result)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("failed to convert result")
|
||||||
|
}
|
||||||
|
newResult.CNIVersion = ImplementedSpecVersion
|
||||||
|
return newResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResultFromResult(result types.Result) (*Result, error) {
|
||||||
|
version := result.Version()
|
||||||
|
for _, converter := range resultConverters {
|
||||||
|
for _, supportedVersion := range converter.versions {
|
||||||
|
if version == supportedVersion {
|
||||||
|
return converter.convert(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unsupported CNI result22 version %q", version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result is what gets returned from the plugin (via stdout) to the caller
|
||||||
|
type Result struct {
|
||||||
|
CNIVersion string `json:"cniVersion,omitempty"`
|
||||||
|
Interfaces []*Interface `json:"interfaces,omitempty"`
|
||||||
|
IPs []*IPConfig `json:"ips,omitempty"`
|
||||||
|
Routes []*types.Route `json:"routes,omitempty"`
|
||||||
|
DNS types.DNS `json:"dns,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to the older 0.2.0 CNI spec Result type
|
||||||
|
func (r *Result) convertTo020() (*types020.Result, error) {
|
||||||
|
oldResult := &types020.Result{
|
||||||
|
CNIVersion: types020.ImplementedSpecVersion,
|
||||||
|
DNS: r.DNS,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ip := range r.IPs {
|
||||||
|
// Only convert the first IP address of each version as 0.2.0
|
||||||
|
// and earlier cannot handle multiple IP addresses
|
||||||
|
if ip.Version == "4" && oldResult.IP4 == nil {
|
||||||
|
oldResult.IP4 = &types020.IPConfig{
|
||||||
|
IP: ip.Address,
|
||||||
|
Gateway: ip.Gateway,
|
||||||
|
}
|
||||||
|
} else if ip.Version == "6" && oldResult.IP6 == nil {
|
||||||
|
oldResult.IP6 = &types020.IPConfig{
|
||||||
|
IP: ip.Address,
|
||||||
|
Gateway: ip.Gateway,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldResult.IP4 != nil && oldResult.IP6 != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, route := range r.Routes {
|
||||||
|
is4 := route.Dst.IP.To4() != nil
|
||||||
|
if is4 && oldResult.IP4 != nil {
|
||||||
|
oldResult.IP4.Routes = append(oldResult.IP4.Routes, types.Route{
|
||||||
|
Dst: route.Dst,
|
||||||
|
GW: route.GW,
|
||||||
|
})
|
||||||
|
} else if !is4 && oldResult.IP6 != nil {
|
||||||
|
oldResult.IP6.Routes = append(oldResult.IP6.Routes, types.Route{
|
||||||
|
Dst: route.Dst,
|
||||||
|
GW: route.GW,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldResult.IP4 == nil && oldResult.IP6 == nil {
|
||||||
|
return nil, fmt.Errorf("cannot convert: no valid IP addresses")
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) Version() string {
|
||||||
|
return ImplementedSpecVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) GetAsVersion(version string) (types.Result, error) {
|
||||||
|
switch version {
|
||||||
|
case "0.3.0", ImplementedSpecVersion:
|
||||||
|
r.CNIVersion = version
|
||||||
|
return r, nil
|
||||||
|
case types020.SupportedVersions[0], types020.SupportedVersions[1], types020.SupportedVersions[2]:
|
||||||
|
return r.convertTo020()
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("cannot convert version 0.3.x to %q", version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Result) Print() error {
|
||||||
|
data, err := json.MarshalIndent(r, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = os.Stdout.Write(data)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a formatted string in the form of "[Interfaces: $1,][ IP: $2,] DNS: $3" where
|
||||||
|
// $1 represents the receiver's Interfaces, $2 represents the receiver's IP addresses and $3 the
|
||||||
|
// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
|
||||||
|
func (r *Result) String() string {
|
||||||
|
var str string
|
||||||
|
if len(r.Interfaces) > 0 {
|
||||||
|
str += fmt.Sprintf("Interfaces:%+v, ", r.Interfaces)
|
||||||
|
}
|
||||||
|
if len(r.IPs) > 0 {
|
||||||
|
str += fmt.Sprintf("IP:%+v, ", r.IPs)
|
||||||
|
}
|
||||||
|
if len(r.Routes) > 0 {
|
||||||
|
str += fmt.Sprintf("Routes:%+v, ", r.Routes)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert this old version result to the current CNI version result
|
||||||
|
func (r *Result) Convert() (*Result, error) {
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface contains values about the created interfaces
|
||||||
|
type Interface struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Mac string `json:"mac,omitempty"`
|
||||||
|
Sandbox string `json:"sandbox,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Interface) String() string {
|
||||||
|
return fmt.Sprintf("%+v", *i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int returns a pointer to the int value passed in. Used to
|
||||||
|
// set the IPConfig.Interface field.
|
||||||
|
func Int(v int) *int {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPConfig contains values necessary to configure an IP address on an interface
|
||||||
|
type IPConfig struct {
|
||||||
|
// IP version, either "4" or "6"
|
||||||
|
Version string
|
||||||
|
// Index into Result structs Interfaces list
|
||||||
|
Interface *int
|
||||||
|
Address net.IPNet
|
||||||
|
Gateway net.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *IPConfig) String() string {
|
||||||
|
return fmt.Sprintf("%+v", *i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON (un)marshallable types
|
||||||
|
type ipConfig struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
Interface *int `json:"interface,omitempty"`
|
||||||
|
Address types.IPNet `json:"address"`
|
||||||
|
Gateway net.IP `json:"gateway,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *IPConfig) MarshalJSON() ([]byte, error) {
|
||||||
|
ipc := ipConfig{
|
||||||
|
Version: c.Version,
|
||||||
|
Interface: c.Interface,
|
||||||
|
Address: types.IPNet(c.Address),
|
||||||
|
Gateway: c.Gateway,
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(ipc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *IPConfig) UnmarshalJSON(data []byte) error {
|
||||||
|
ipc := ipConfig{}
|
||||||
|
if err := json.Unmarshal(data, &ipc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Version = ipc.Version
|
||||||
|
c.Interface = ipc.Interface
|
||||||
|
c.Address = net.IPNet(ipc.Address)
|
||||||
|
c.Gateway = ipc.Gateway
|
||||||
|
return nil
|
||||||
|
}
|
96
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
96
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
@ -16,6 +16,7 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
@ -61,42 +62,46 @@ type NetConf struct {
|
|||||||
|
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
|
Capabilities map[string]bool `json:"capabilities,omitempty"`
|
||||||
IPAM struct {
|
IPAM struct {
|
||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
} `json:"ipam,omitempty"`
|
} `json:"ipam,omitempty"`
|
||||||
DNS DNS `json:"dns"`
|
DNS DNS `json:"dns"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Result is what gets returned from the plugin (via stdout) to the caller
|
// NetConfList describes an ordered list of networks.
|
||||||
type Result struct {
|
type NetConfList struct {
|
||||||
IP4 *IPConfig `json:"ip4,omitempty"`
|
CNIVersion string `json:"cniVersion,omitempty"`
|
||||||
IP6 *IPConfig `json:"ip6,omitempty"`
|
|
||||||
DNS DNS `json:"dns,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
Plugins []*NetConf `json:"plugins,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Result) Print() error {
|
type ResultFactoryFunc func([]byte) (Result, error)
|
||||||
return prettyPrint(r)
|
|
||||||
|
// Result is an interface that provides the result of plugin execution
|
||||||
|
type Result interface {
|
||||||
|
// The highest CNI specification result verison the result supports
|
||||||
|
// without having to convert
|
||||||
|
Version() string
|
||||||
|
|
||||||
|
// Returns the result converted into the requested CNI specification
|
||||||
|
// result version, or an error if conversion failed
|
||||||
|
GetAsVersion(version string) (Result, error)
|
||||||
|
|
||||||
|
// Prints the result in JSON format to stdout
|
||||||
|
Print() error
|
||||||
|
|
||||||
|
// Returns a JSON string representation of the result
|
||||||
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a formatted string in the form of "[IP4: $1,][ IP6: $2,] DNS: $3" where
|
func PrintResult(result Result, version string) error {
|
||||||
// $1 represents the receiver's IPv4, $2 represents the receiver's IPv6 and $3 the
|
newResult, err := result.GetAsVersion(version)
|
||||||
// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
|
if err != nil {
|
||||||
func (r *Result) String() string {
|
return err
|
||||||
var str string
|
|
||||||
if r.IP4 != nil {
|
|
||||||
str = fmt.Sprintf("IP4:%+v, ", *r.IP4)
|
|
||||||
}
|
}
|
||||||
if r.IP6 != nil {
|
return newResult.Print()
|
||||||
str += fmt.Sprintf("IP6:%+v, ", *r.IP6)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPConfig contains values necessary to configure an interface
|
|
||||||
type IPConfig struct {
|
|
||||||
IP net.IPNet
|
|
||||||
Gateway net.IP
|
|
||||||
Routes []Route
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNS contains values interesting for DNS resolvers
|
// DNS contains values interesting for DNS resolvers
|
||||||
@ -112,6 +117,10 @@ type Route struct {
|
|||||||
GW net.IP
|
GW net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Route) String() string {
|
||||||
|
return fmt.Sprintf("%+v", *r)
|
||||||
|
}
|
||||||
|
|
||||||
// Well known error codes
|
// Well known error codes
|
||||||
// see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes
|
// see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes
|
||||||
const (
|
const (
|
||||||
@ -127,7 +136,11 @@ type Error struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
func (e *Error) Error() string {
|
||||||
return e.Msg
|
details := ""
|
||||||
|
if e.Details != "" {
|
||||||
|
details = fmt.Sprintf("; %v", e.Details)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v%v", e.Msg, details)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Error) Print() error {
|
func (e *Error) Print() error {
|
||||||
@ -138,39 +151,11 @@ func (e *Error) Print() error {
|
|||||||
// for our custom IPNet type
|
// for our custom IPNet type
|
||||||
|
|
||||||
// JSON (un)marshallable types
|
// JSON (un)marshallable types
|
||||||
type ipConfig struct {
|
|
||||||
IP IPNet `json:"ip"`
|
|
||||||
Gateway net.IP `json:"gateway,omitempty"`
|
|
||||||
Routes []Route `json:"routes,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type route struct {
|
type route struct {
|
||||||
Dst IPNet `json:"dst"`
|
Dst IPNet `json:"dst"`
|
||||||
GW net.IP `json:"gw,omitempty"`
|
GW net.IP `json:"gw,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *IPConfig) MarshalJSON() ([]byte, error) {
|
|
||||||
ipc := ipConfig{
|
|
||||||
IP: IPNet(c.IP),
|
|
||||||
Gateway: c.Gateway,
|
|
||||||
Routes: c.Routes,
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.Marshal(ipc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *IPConfig) UnmarshalJSON(data []byte) error {
|
|
||||||
ipc := ipConfig{}
|
|
||||||
if err := json.Unmarshal(data, &ipc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
c.IP = net.IPNet(ipc.IP)
|
|
||||||
c.Gateway = ipc.Gateway
|
|
||||||
c.Routes = ipc.Routes
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Route) UnmarshalJSON(data []byte) error {
|
func (r *Route) UnmarshalJSON(data []byte) error {
|
||||||
rt := route{}
|
rt := route{}
|
||||||
if err := json.Unmarshal(data, &rt); err != nil {
|
if err := json.Unmarshal(data, &rt); err != nil {
|
||||||
@ -199,3 +184,6 @@ func prettyPrint(obj interface{}) error {
|
|||||||
_, err = os.Stdout.Write(data)
|
_, err = os.Stdout.Write(data)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotImplementedError is used to indicate that a method is not implemented for the given platform
|
||||||
|
var NotImplementedError = errors.New("Not Implemented")
|
||||||
|
16
vendor/github.com/containernetworking/cni/pkg/version/reconcile.go
generated
vendored
16
vendor/github.com/containernetworking/cni/pkg/version/reconcile.go
generated
vendored
@ -18,11 +18,11 @@ import "fmt"
|
|||||||
|
|
||||||
type ErrorIncompatible struct {
|
type ErrorIncompatible struct {
|
||||||
Config string
|
Config string
|
||||||
Plugin []string
|
Supported []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrorIncompatible) Details() string {
|
func (e *ErrorIncompatible) Details() string {
|
||||||
return fmt.Sprintf("config is %q, plugin supports %q", e.Config, e.Plugin)
|
return fmt.Sprintf("config is %q, plugin supports %q", e.Config, e.Supported)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ErrorIncompatible) Error() string {
|
func (e *ErrorIncompatible) Error() string {
|
||||||
@ -31,17 +31,19 @@ func (e *ErrorIncompatible) Error() string {
|
|||||||
|
|
||||||
type Reconciler struct{}
|
type Reconciler struct{}
|
||||||
|
|
||||||
func (*Reconciler) Check(configVersion string, pluginInfo PluginInfo) *ErrorIncompatible {
|
func (r *Reconciler) Check(configVersion string, pluginInfo PluginInfo) *ErrorIncompatible {
|
||||||
pluginVersions := pluginInfo.SupportedVersions()
|
return r.CheckRaw(configVersion, pluginInfo.SupportedVersions())
|
||||||
|
}
|
||||||
|
|
||||||
for _, pluginVersion := range pluginVersions {
|
func (*Reconciler) CheckRaw(configVersion string, supportedVersions []string) *ErrorIncompatible {
|
||||||
if configVersion == pluginVersion {
|
for _, supportedVersion := range supportedVersions {
|
||||||
|
if configVersion == supportedVersion {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ErrorIncompatible{
|
return &ErrorIncompatible{
|
||||||
Config: configVersion,
|
Config: configVersion,
|
||||||
Plugin: pluginVersions,
|
Supported: supportedVersions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
34
vendor/github.com/containernetworking/cni/pkg/version/version.go
generated
vendored
34
vendor/github.com/containernetworking/cni/pkg/version/version.go
generated
vendored
@ -14,9 +14,17 @@
|
|||||||
|
|
||||||
package version
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
|
"github.com/containernetworking/cni/pkg/types/020"
|
||||||
|
"github.com/containernetworking/cni/pkg/types/current"
|
||||||
|
)
|
||||||
|
|
||||||
// Current reports the version of the CNI spec implemented by this library
|
// Current reports the version of the CNI spec implemented by this library
|
||||||
func Current() string {
|
func Current() string {
|
||||||
return "0.2.0"
|
return "0.3.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy PluginInfo describes a plugin that is backwards compatible with the
|
// Legacy PluginInfo describes a plugin that is backwards compatible with the
|
||||||
@ -27,3 +35,27 @@ func Current() string {
|
|||||||
// Any future CNI spec versions which meet this definition should be added to
|
// Any future CNI spec versions which meet this definition should be added to
|
||||||
// this list.
|
// this list.
|
||||||
var Legacy = PluginSupports("0.1.0", "0.2.0")
|
var Legacy = PluginSupports("0.1.0", "0.2.0")
|
||||||
|
var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1")
|
||||||
|
|
||||||
|
var resultFactories = []struct {
|
||||||
|
supportedVersions []string
|
||||||
|
newResult types.ResultFactoryFunc
|
||||||
|
}{
|
||||||
|
{current.SupportedVersions, current.NewResult},
|
||||||
|
{types020.SupportedVersions, types020.NewResult},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds a Result object matching the requested version (if any) and asks
|
||||||
|
// that object to parse the plugin result, returning an error if parsing failed.
|
||||||
|
func NewResult(version string, resultBytes []byte) (types.Result, error) {
|
||||||
|
reconciler := &Reconciler{}
|
||||||
|
for _, resultFactory := range resultFactories {
|
||||||
|
err := reconciler.CheckRaw(version, resultFactory.supportedVersions)
|
||||||
|
if err == nil {
|
||||||
|
// Result supports this version
|
||||||
|
return resultFactory.newResult(resultBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("unsupported CNI result version %q", version)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user