github.com/mccv1r0/cni@v0.7.0-alpha1/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 "crypto/sha512" 19 "encoding/json" 20 "fmt" 21 "os" 22 "path/filepath" 23 "strings" 24 25 "github.com/containernetworking/cni/libcni" 26 ) 27 28 const ( 29 EnvCNIPath = "CNI_PATH" 30 EnvNetDir = "NETCONFPATH" 31 EnvCapabilityArgs = "CAP_ARGS" 32 EnvCNIArgs = "CNI_ARGS" 33 34 DefaultNetDir = "/etc/cni/net.d" 35 36 CmdAdd = "add" 37 CmdDel = "del" 38 ) 39 40 func parseArgs(args string) ([][2]string, error) { 41 var result [][2]string 42 43 pairs := strings.Split(args, ";") 44 for _, pair := range pairs { 45 kv := strings.Split(pair, "=") 46 if len(kv) != 2 || kv[0] == "" || kv[1] == "" { 47 return nil, fmt.Errorf("invalid CNI_ARGS pair %q", pair) 48 } 49 50 result = append(result, [2]string{kv[0], kv[1]}) 51 } 52 53 return result, nil 54 } 55 56 func main() { 57 if len(os.Args) < 3 { 58 usage() 59 return 60 } 61 62 netdir := os.Getenv(EnvNetDir) 63 if netdir == "" { 64 netdir = DefaultNetDir 65 } 66 netconf, err := libcni.LoadConfList(netdir, os.Args[2]) 67 if err != nil { 68 exit(err) 69 } 70 71 var capabilityArgs map[string]interface{} 72 capabilityArgsValue := os.Getenv(EnvCapabilityArgs) 73 if len(capabilityArgsValue) > 0 { 74 if err = json.Unmarshal([]byte(capabilityArgsValue), &capabilityArgs); err != nil { 75 exit(err) 76 } 77 } 78 79 var cniArgs [][2]string 80 args := os.Getenv(EnvCNIArgs) 81 if len(args) > 0 { 82 cniArgs, err = parseArgs(args) 83 if err != nil { 84 exit(err) 85 } 86 } 87 88 netns := os.Args[3] 89 netns, err = filepath.Abs(netns) 90 if err != nil { 91 exit(err) 92 } 93 94 // Generate the containerid by hashing the netns path 95 s := sha512.Sum512([]byte(netns)) 96 containerID := fmt.Sprintf("cnitool-%x", s[:10]) 97 98 cninet := libcni.NewCNIConfig(filepath.SplitList(os.Getenv(EnvCNIPath)), nil) 99 100 rt := &libcni.RuntimeConf{ 101 ContainerID: containerID, 102 NetNS: netns, 103 IfName: "eth0", 104 Args: cniArgs, 105 CapabilityArgs: capabilityArgs, 106 } 107 108 switch os.Args[1] { 109 case CmdAdd: 110 result, err := cninet.AddNetworkList(netconf, rt) 111 if result != nil { 112 _ = result.Print() 113 } 114 exit(err) 115 case CmdDel: 116 exit(cninet.DelNetworkList(netconf, rt)) 117 } 118 } 119 120 func usage() { 121 exe := filepath.Base(os.Args[0]) 122 123 fmt.Fprintf(os.Stderr, "%s: Add or remove network interfaces from a network namespace\n", exe) 124 fmt.Fprintf(os.Stderr, " %s %s <net> <netns>\n", exe, CmdAdd) 125 fmt.Fprintf(os.Stderr, " %s %s <net> <netns>\n", exe, CmdDel) 126 os.Exit(1) 127 } 128 129 func exit(err error) { 130 if err != nil { 131 fmt.Fprintf(os.Stderr, "%s\n", err) 132 os.Exit(1) 133 } 134 os.Exit(0) 135 }