aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/containernetworking/cni/libcni/conf.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/containernetworking/cni/libcni/conf.go')
-rw-r--r--vendor/github.com/containernetworking/cni/libcni/conf.go256
1 files changed, 256 insertions, 0 deletions
diff --git a/vendor/github.com/containernetworking/cni/libcni/conf.go b/vendor/github.com/containernetworking/cni/libcni/conf.go
new file mode 100644
index 000000000..c7738c665
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/libcni/conf.go
@@ -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)
+}