vendor: add libcni
This commit is contained in:
parent
539174f8c8
commit
b47d5b7c0a
5
Godeps/Godeps.json
generated
5
Godeps/Godeps.json
generated
@ -6,6 +6,11 @@
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/containernetworking/cni/libcni",
|
||||
"Comment": "v0.5.2",
|
||||
"Rev": "137b4975ecab6e1f0c24c1e3c228a50a3cfba75e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/containernetworking/cni/pkg/invoke",
|
||||
"Comment": "v0.5.2",
|
||||
|
219
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
Normal file
219
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
// Copyright 2015 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 libcni
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/invoke"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
)
|
||||
|
||||
type RuntimeConf struct {
|
||||
ContainerID string
|
||||
NetNS string
|
||||
IfName 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 {
|
||||
Network *types.NetConf
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
type NetworkConfigList struct {
|
||||
Name string
|
||||
CNIVersion string
|
||||
Plugins []*NetworkConfig
|
||||
Bytes []byte
|
||||
}
|
||||
|
||||
type CNI interface {
|
||||
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
|
||||
}
|
||||
|
||||
type CNIConfig struct {
|
||||
Path []string
|
||||
}
|
||||
|
||||
// CNIConfig implements the CNI interface
|
||||
var _ CNI = &CNIConfig{}
|
||||
|
||||
func buildOneConfig(list *NetworkConfigList, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, 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)
|
||||
if err != nil {
|
||||
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))
|
||||
}
|
||||
|
||||
// DelNetwork executes the plugin with the DEL command
|
||||
func (c *CNIConfig) DelNetwork(net *NetworkConfig, rt *RuntimeConf) error {
|
||||
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
net, err = injectRuntimeConfig(net, rt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return invoke.ExecPluginWithoutResult(pluginPath, net.Bytes, c.args("DEL", rt))
|
||||
}
|
||||
|
||||
// GetVersionInfo reports which versions of the CNI spec are supported by
|
||||
// the given plugin.
|
||||
func (c *CNIConfig) GetVersionInfo(pluginType string) (version.PluginInfo, error) {
|
||||
pluginPath, err := invoke.FindInPath(pluginType, c.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return invoke.GetVersionInfo(pluginPath)
|
||||
}
|
||||
|
||||
// =====
|
||||
func (c *CNIConfig) args(action string, rt *RuntimeConf) *invoke.Args {
|
||||
return &invoke.Args{
|
||||
Command: action,
|
||||
ContainerID: rt.ContainerID,
|
||||
NetNS: rt.NetNS,
|
||||
PluginArgs: rt.Args,
|
||||
IfName: rt.IfName,
|
||||
Path: strings.Join(c.Path, string(os.PathListSeparator)),
|
||||
}
|
||||
}
|
256
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
Normal file
256
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
// Copyright 2015 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 libcni
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"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) {
|
||||
conf := &NetworkConfig{Bytes: bytes}
|
||||
if err := json.Unmarshal(bytes, &conf.Network); err != nil {
|
||||
return nil, fmt.Errorf("error parsing configuration: %s", err)
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
func ConfFromFile(filename string) (*NetworkConfig, error) {
|
||||
bytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading %s: %s", filename, err)
|
||||
}
|
||||
return ConfFromBytes(bytes)
|
||||
}
|
||||
|
||||
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
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
switch {
|
||||
case err == nil: // break
|
||||
case os.IsNotExist(err):
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
confFiles := []string{}
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
fileExt := filepath.Ext(f.Name())
|
||||
for _, ext := range extensions {
|
||||
if fileExt == ext {
|
||||
confFiles = append(confFiles, filepath.Join(dir, f.Name()))
|
||||
}
|
||||
}
|
||||
}
|
||||
return confFiles, nil
|
||||
}
|
||||
|
||||
func LoadConf(dir, name string) (*NetworkConfig, error) {
|
||||
files, err := ConfFiles(dir, []string{".conf", ".json"})
|
||||
switch {
|
||||
case err != nil:
|
||||
return nil, err
|
||||
case len(files) == 0:
|
||||
return nil, NoConfigsFoundError{Dir: dir}
|
||||
}
|
||||
sort.Strings(files)
|
||||
|
||||
for _, confFile := range files {
|
||||
conf, err := ConfFromFile(confFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if conf.Network.Name == name {
|
||||
return conf, nil
|
||||
}
|
||||
}
|
||||
return nil, NotFoundError{dir, name}
|
||||
}
|
||||
|
||||
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{})
|
||||
err := json.Unmarshal(original.Bytes, &config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unmarshal existing network bytes: %s", err)
|
||||
}
|
||||
|
||||
for key, value := range newValues {
|
||||
if key == "" {
|
||||
return nil, fmt.Errorf("keys cannot be empty")
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
return nil, fmt.Errorf("key '%s' value must not be nil", key)
|
||||
}
|
||||
|
||||
config[key] = value
|
||||
}
|
||||
|
||||
newBytes, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user