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 }