github.com/john-lin/cni@v0.6.0-rc1.0.20170712150331-b69e640cc0e2/pkg/version/legacy_examples/example_runtime.go (about)

     1  // Copyright 2016 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 legacy_examples
    16  
    17  import (
    18  	"fmt"
    19  	"io/ioutil"
    20  	"os"
    21  
    22  	noop_debug "github.com/containernetworking/cni/plugins/test/noop/debug"
    23  )
    24  
    25  // An ExampleRuntime is a small program that uses libcni to invoke a network plugin.
    26  // It should call ADD and DELETE, verifying all intermediate steps
    27  // and data structures.
    28  type ExampleRuntime struct {
    29  	Example
    30  	NetConfs []string // The network configuration names to pass
    31  }
    32  
    33  type exampleNetConfTemplate struct {
    34  	conf   string
    35  	result string
    36  }
    37  
    38  // NetConfs are various versioned network configuration files. Examples should
    39  // specify which version they expect
    40  var netConfTemplates = map[string]exampleNetConfTemplate{
    41  	"unversioned": {
    42  		conf: `{
    43  	"name": "default",
    44  	"type": "noop",
    45  	"debugFile": "%s"
    46  }`,
    47  		result: `{
    48  	"ip4": {
    49  		"ip": "1.2.3.30/24",
    50  		"gateway": "1.2.3.1",
    51  		"routes": [
    52  			{
    53  				"dst": "15.5.6.0/24",
    54  				"gw": "15.5.6.8"
    55  			}
    56  		]
    57  	},
    58  	"ip6": {
    59  		"ip": "abcd:1234:ffff::cdde/64",
    60  		"gateway": "abcd:1234:ffff::1",
    61  		"routes": [
    62  			{
    63  				"dst": "1111:dddd::/80",
    64  				"gw": "1111:dddd::aaaa"
    65  			}
    66  		]
    67  	},
    68  	"dns":{}
    69  }`,
    70  	},
    71  	"0.1.0": {
    72  		conf: `{
    73  	"cniVersion": "0.1.0",
    74  	"name": "default",
    75  	"type": "noop",
    76  	"debugFile": "%s"
    77  }`,
    78  		result: `{
    79  	"cniVersion": "0.1.0",
    80  	"ip4": {
    81  		"ip": "1.2.3.30/24",
    82  		"gateway": "1.2.3.1",
    83  		"routes": [
    84  			{
    85  				"dst": "15.5.6.0/24",
    86  				"gw": "15.5.6.8"
    87  			}
    88  		]
    89  	},
    90  	"ip6": {
    91  		"ip": "abcd:1234:ffff::cdde/64",
    92  		"gateway": "abcd:1234:ffff::1",
    93  		"routes": [
    94  			{
    95  				"dst": "1111:dddd::/80",
    96  				"gw": "1111:dddd::aaaa"
    97  			}
    98  		]
    99  	},
   100  	"dns":{}
   101  }`,
   102  	},
   103  }
   104  
   105  func (e *ExampleRuntime) GenerateNetConf(name string) (*ExampleNetConf, error) {
   106  	template, ok := netConfTemplates[name]
   107  	if !ok {
   108  		return nil, fmt.Errorf("unknown example net config template %q", name)
   109  	}
   110  
   111  	debugFile, err := ioutil.TempFile("", "cni_debug")
   112  	if err != nil {
   113  		return nil, fmt.Errorf("failed to create noop plugin debug file: %v", err)
   114  	}
   115  	debugFilePath := debugFile.Name()
   116  
   117  	debug := &noop_debug.Debug{
   118  		ReportResult: template.result,
   119  	}
   120  	if err := debug.WriteDebug(debugFilePath); err != nil {
   121  		os.Remove(debugFilePath)
   122  		return nil, fmt.Errorf("failed to write noop plugin debug file %q: %v", debugFilePath, err)
   123  	}
   124  	conf := &ExampleNetConf{
   125  		Config:        fmt.Sprintf(template.conf, debugFilePath),
   126  		debugFilePath: debugFilePath,
   127  	}
   128  
   129  	return conf, nil
   130  }
   131  
   132  type ExampleNetConf struct {
   133  	Config        string
   134  	debugFilePath string
   135  }
   136  
   137  func (c *ExampleNetConf) Cleanup() {
   138  	os.Remove(c.debugFilePath)
   139  }
   140  
   141  // V010_Runtime creates a simple noop network configuration, then
   142  // executes libcni against the the noop test plugin.
   143  var V010_Runtime = ExampleRuntime{
   144  	NetConfs: []string{"unversioned", "0.1.0"},
   145  	Example: Example{
   146  		Name:          "example_invoker_v010",
   147  		CNIRepoGitRef: "c0d34c69", //version with ns.Do
   148  		PluginSource: `package main
   149  
   150  import (
   151  	"fmt"
   152  	"io/ioutil"
   153  	"net"
   154  	"os"
   155  
   156  	"github.com/containernetworking/cni/pkg/ns"
   157  	"github.com/containernetworking/cni/libcni"
   158  )
   159  
   160  func main(){
   161  	code :=	exec()
   162  	os.Exit(code)
   163  }
   164  
   165  func exec() int {
   166  	confBytes, err := ioutil.ReadAll(os.Stdin)
   167  	if err != nil {
   168  		fmt.Printf("could not read netconfig from stdin: %+v", err)
   169  		return 1
   170  	}
   171  
   172  	netConf, err := libcni.ConfFromBytes(confBytes)
   173  	if err != nil {
   174  		fmt.Printf("could not parse netconfig: %+v", err)
   175  		return 1
   176  	}
   177  	fmt.Printf("Parsed network configuration: %+v\n", netConf.Network)
   178  
   179  	if len(os.Args) == 1 {
   180  		fmt.Printf("Expect CNI plugin paths in argv")
   181  		return 1
   182  	}
   183  
   184  	targetNs, err := ns.NewNS()
   185  	if err !=  nil {
   186  		fmt.Printf("Could not create ns: %+v", err)
   187  		return 1
   188  	}
   189  	defer targetNs.Close()
   190  
   191  	ifName := "eth0"
   192  
   193  	runtimeConf := &libcni.RuntimeConf{
   194  		ContainerID: "some-container-id",
   195  		NetNS:       targetNs.Path(),
   196  		IfName:      ifName,
   197  	}
   198  
   199  	cniConfig := &libcni.CNIConfig{Path: os.Args[1:]}
   200  
   201  	result, err := cniConfig.AddNetwork(netConf, runtimeConf)
   202  	if err != nil {
   203  		fmt.Printf("AddNetwork failed: %+v", err)
   204  		return 2
   205  	}
   206  	fmt.Printf("AddNetwork result: %+v", result)
   207  
   208  	// Validate expected results
   209  	const expectedIP4 string = "1.2.3.30/24"
   210  	if result.IP4.IP.String() != expectedIP4 {
   211  		fmt.Printf("Expected IPv4 address %q, got %q", expectedIP4, result.IP4.IP.String())
   212  		return 3
   213  	}
   214  	const expectedIP6 string = "abcd:1234:ffff::cdde/64"
   215  	if result.IP6.IP.String() != expectedIP6 {
   216  		fmt.Printf("Expected IPv6 address %q, got %q", expectedIP6, result.IP6.IP.String())
   217  		return 4
   218  	}
   219  
   220  	err = cniConfig.DelNetwork(netConf, runtimeConf)
   221  	if err != nil {
   222  		fmt.Printf("DelNetwork failed: %v", err)
   223  		return 5
   224  	}
   225  
   226  	err = targetNs.Do(func(ns.NetNS) error {
   227  		_, err := net.InterfaceByName(ifName)
   228  		if err == nil {
   229  			return fmt.Errorf("interface was not deleted")
   230  		}
   231  		return nil
   232  	})
   233  	if err != nil {
   234  		fmt.Println(err)
   235  		return 6
   236  	}
   237  
   238  	return 0
   239  }
   240  `,
   241  	},
   242  }