github.com/baraj55/containernetworking-cni@v0.7.2-0.20200219164625-56ace59a9e7f/cnitool/cnitool.go (about)

     1  // Copyright 2015 CNI authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"context"
    19  	"crypto/sha512"
    20  	"encoding/json"
    21  	"fmt"
    22  	"os"
    23  	"path/filepath"
    24  	"strings"
    25  
    26  	"github.com/containernetworking/cni/libcni"
    27  )
    28  
    29  const (
    30  	EnvCNIPath        = "CNI_PATH"
    31  	EnvNetDir         = "NETCONFPATH"
    32  	EnvCapabilityArgs = "CAP_ARGS"
    33  	EnvCNIArgs        = "CNI_ARGS"
    34  	EnvCNIIfname      = "CNI_IFNAME"
    35  
    36  	DefaultNetDir = "/etc/cni/net.d"
    37  
    38  	CmdAdd   = "add"
    39  	CmdCheck = "check"
    40  	CmdDel   = "del"
    41  )
    42  
    43  func parseArgs(args string) ([][2]string, error) {
    44  	var result [][2]string
    45  
    46  	pairs := strings.Split(args, ";")
    47  	for _, pair := range pairs {
    48  		kv := strings.Split(pair, "=")
    49  		if len(kv) != 2 || kv[0] == "" || kv[1] == "" {
    50  			return nil, fmt.Errorf("invalid CNI_ARGS pair %q", pair)
    51  		}
    52  
    53  		result = append(result, [2]string{kv[0], kv[1]})
    54  	}
    55  
    56  	return result, nil
    57  }
    58  
    59  func main() {
    60  	if len(os.Args) < 4 {
    61  		usage()
    62  		return
    63  	}
    64  
    65  	netdir := os.Getenv(EnvNetDir)
    66  	if netdir == "" {
    67  		netdir = DefaultNetDir
    68  	}
    69  	netconf, err := libcni.LoadConfList(netdir, os.Args[2])
    70  	if err != nil {
    71  		exit(err)
    72  	}
    73  
    74  	var capabilityArgs map[string]interface{}
    75  	capabilityArgsValue := os.Getenv(EnvCapabilityArgs)
    76  	if len(capabilityArgsValue) > 0 {
    77  		if err = json.Unmarshal([]byte(capabilityArgsValue), &capabilityArgs); err != nil {
    78  			exit(err)
    79  		}
    80  	}
    81  
    82  	var cniArgs [][2]string
    83  	args := os.Getenv(EnvCNIArgs)
    84  	if len(args) > 0 {
    85  		cniArgs, err = parseArgs(args)
    86  		if err != nil {
    87  			exit(err)
    88  		}
    89  	}
    90  
    91  	ifName, ok := os.LookupEnv(EnvCNIIfname)
    92  	if !ok {
    93  		ifName = "eth0"
    94  	}
    95  
    96  	netns := os.Args[3]
    97  	netns, err = filepath.Abs(netns)
    98  	if err != nil {
    99  		exit(err)
   100  	}
   101  
   102  	// Generate the containerid by hashing the netns path
   103  	s := sha512.Sum512([]byte(netns))
   104  	containerID := fmt.Sprintf("cnitool-%x", s[:10])
   105  
   106  	cninet := libcni.NewCNIConfig(filepath.SplitList(os.Getenv(EnvCNIPath)), nil)
   107  
   108  	rt := &libcni.RuntimeConf{
   109  		ContainerID:    containerID,
   110  		NetNS:          netns,
   111  		IfName:         ifName,
   112  		Args:           cniArgs,
   113  		CapabilityArgs: capabilityArgs,
   114  	}
   115  
   116  	switch os.Args[1] {
   117  	case CmdAdd:
   118  		result, err := cninet.AddNetworkList(context.TODO(), netconf, rt)
   119  		if result != nil {
   120  			_ = result.Print()
   121  		}
   122  		exit(err)
   123  	case CmdCheck:
   124  		err := cninet.CheckNetworkList(context.TODO(), netconf, rt)
   125  		exit(err)
   126  	case CmdDel:
   127  		exit(cninet.DelNetworkList(context.TODO(), netconf, rt))
   128  	}
   129  }
   130  
   131  func usage() {
   132  	exe := filepath.Base(os.Args[0])
   133  
   134  	fmt.Fprintf(os.Stderr, "%s: Add, check, or remove network interfaces from a network namespace\n", exe)
   135  	fmt.Fprintf(os.Stderr, "  %s add   <net> <netns>\n", exe)
   136  	fmt.Fprintf(os.Stderr, "  %s check <net> <netns>\n", exe)
   137  	fmt.Fprintf(os.Stderr, "  %s del   <net> <netns>\n", exe)
   138  	os.Exit(1)
   139  }
   140  
   141  func exit(err error) {
   142  	if err != nil {
   143  		fmt.Fprintf(os.Stderr, "%s\n", err)
   144  		os.Exit(1)
   145  	}
   146  	os.Exit(0)
   147  }