github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/state/apiserver/networker/networker_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package networker_test
     5  
     6  import (
     7  	gc "launchpad.net/gocheck"
     8  
     9  	"github.com/juju/juju/instance"
    10  	"github.com/juju/juju/juju/testing"
    11  	"github.com/juju/juju/network"
    12  	"github.com/juju/juju/state"
    13  	"github.com/juju/juju/state/api/params"
    14  	"github.com/juju/juju/state/apiserver/common"
    15  	"github.com/juju/juju/state/apiserver/networker"
    16  	apiservertesting "github.com/juju/juju/state/apiserver/testing"
    17  )
    18  
    19  type networkerSuite struct {
    20  	testing.JujuConnSuite
    21  
    22  	networks []state.NetworkInfo
    23  
    24  	machine         *state.Machine
    25  	container       *state.Machine
    26  	nestedContainer *state.Machine
    27  
    28  	machineIfaces         []state.NetworkInterfaceInfo
    29  	containerIfaces       []state.NetworkInterfaceInfo
    30  	nestedContainerIfaces []state.NetworkInterfaceInfo
    31  
    32  	authorizer apiservertesting.FakeAuthorizer
    33  	resources  *common.Resources
    34  	networker  *networker.NetworkerAPI
    35  }
    36  
    37  var _ = gc.Suite(&networkerSuite{})
    38  
    39  // Create several networks.
    40  func (s *networkerSuite) setUpNetworks(c *gc.C) {
    41  	s.networks = []state.NetworkInfo{{
    42  		Name:       "net1",
    43  		ProviderId: "net1",
    44  		CIDR:       "0.1.2.0/24",
    45  		VLANTag:    0,
    46  	}, {
    47  		Name:       "vlan42",
    48  		ProviderId: "vlan42",
    49  		CIDR:       "0.2.2.0/24",
    50  		VLANTag:    42,
    51  	}, {
    52  		Name:       "vlan69",
    53  		ProviderId: "vlan69",
    54  		CIDR:       "0.3.2.0/24",
    55  		VLANTag:    69,
    56  	}, {
    57  		Name:       "vlan123",
    58  		ProviderId: "vlan123",
    59  		CIDR:       "0.4.2.0/24",
    60  		VLANTag:    123,
    61  	}, {
    62  		Name:       "net2",
    63  		ProviderId: "net2",
    64  		CIDR:       "0.5.2.0/24",
    65  		VLANTag:    0,
    66  	}}
    67  }
    68  
    69  // Create a machine to use.
    70  func (s *networkerSuite) setUpMachine(c *gc.C) {
    71  	var err error
    72  	s.machine, err = s.State.AddMachine("quantal", state.JobHostUnits)
    73  	c.Assert(err, gc.IsNil)
    74  	hwChars := instance.MustParseHardware("arch=i386", "mem=4G")
    75  	s.machineIfaces = []state.NetworkInterfaceInfo{{
    76  		MACAddress:    "aa:bb:cc:dd:ee:f0",
    77  		InterfaceName: "eth0",
    78  		NetworkName:   "net1",
    79  		IsVirtual:     false,
    80  	}, {
    81  		MACAddress:    "aa:bb:cc:dd:ee:f1",
    82  		InterfaceName: "eth1",
    83  		NetworkName:   "net1",
    84  		IsVirtual:     false,
    85  	}, {
    86  		MACAddress:    "aa:bb:cc:dd:ee:f1",
    87  		InterfaceName: "eth1.42",
    88  		NetworkName:   "vlan42",
    89  		IsVirtual:     true,
    90  	}, {
    91  		MACAddress:    "aa:bb:cc:dd:ee:f0",
    92  		InterfaceName: "eth0.69",
    93  		NetworkName:   "vlan69",
    94  		IsVirtual:     true,
    95  	}, {
    96  		MACAddress:    "aa:bb:cc:dd:ee:f2",
    97  		InterfaceName: "eth2",
    98  		NetworkName:   "net2",
    99  		IsVirtual:     false,
   100  	}}
   101  	err = s.machine.SetInstanceInfo("i-am", "fake_nonce", &hwChars, s.networks, s.machineIfaces)
   102  	c.Assert(err, gc.IsNil)
   103  }
   104  
   105  // Create and provision a container and a nested container.
   106  func (s *networkerSuite) setUpContainers(c *gc.C) {
   107  	template := state.MachineTemplate{
   108  		Series: "quantal",
   109  		Jobs:   []state.MachineJob{state.JobHostUnits},
   110  	}
   111  	var err error
   112  	s.container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC)
   113  	c.Assert(err, gc.IsNil)
   114  	s.containerIfaces = []state.NetworkInterfaceInfo{{
   115  		MACAddress:    "aa:bb:cc:dd:ee:e0",
   116  		InterfaceName: "eth0",
   117  		NetworkName:   "net1",
   118  		IsVirtual:     false,
   119  	}, {
   120  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   121  		InterfaceName: "eth1",
   122  		NetworkName:   "net1",
   123  		IsVirtual:     false,
   124  	}, {
   125  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   126  		InterfaceName: "eth1.42",
   127  		NetworkName:   "vlan42",
   128  		IsVirtual:     true,
   129  	}}
   130  	hwChars := instance.MustParseHardware("arch=i386", "mem=4G")
   131  	err = s.container.SetInstanceInfo("i-container", "fake_nonce", &hwChars, s.networks[:2],
   132  		s.containerIfaces)
   133  	c.Assert(err, gc.IsNil)
   134  
   135  	s.nestedContainer, err = s.State.AddMachineInsideMachine(template, s.container.Id(), instance.LXC)
   136  	c.Assert(err, gc.IsNil)
   137  	s.nestedContainerIfaces = []state.NetworkInterfaceInfo{{
   138  		MACAddress:    "aa:bb:cc:dd:ee:d0",
   139  		InterfaceName: "eth0",
   140  		NetworkName:   "net1",
   141  	}}
   142  	err = s.nestedContainer.SetInstanceInfo("i-too", "fake_nonce", &hwChars, s.networks[:1],
   143  		s.nestedContainerIfaces)
   144  	c.Assert(err, gc.IsNil)
   145  }
   146  
   147  func (s *networkerSuite) SetUpTest(c *gc.C) {
   148  	s.JujuConnSuite.SetUpTest(c)
   149  
   150  	s.setUpNetworks(c)
   151  	s.setUpMachine(c)
   152  	s.setUpContainers(c)
   153  
   154  	// Create a FakeAuthorizer so we can check permissions,
   155  	// set up assuming we logged in as a machine agent.
   156  	s.authorizer = apiservertesting.FakeAuthorizer{
   157  		LoggedIn:     true,
   158  		MachineAgent: true,
   159  		Tag:          s.machine.Tag(),
   160  	}
   161  
   162  	// Create a networker API for the machine.
   163  	var err error
   164  	s.networker, err = networker.NewNetworkerAPI(
   165  		s.State,
   166  		nil,
   167  		s.authorizer,
   168  	)
   169  	c.Assert(err, gc.IsNil)
   170  }
   171  
   172  func (s *networkerSuite) TestNetworkerNonMachineAgent(c *gc.C) {
   173  	// Fails with not a machine agent
   174  	anAuthorizer := s.authorizer
   175  	anAuthorizer.MachineAgent = false
   176  	aNetworker, err := networker.NewNetworkerAPI(s.State, s.resources, anAuthorizer)
   177  	c.Assert(err, gc.ErrorMatches, "permission denied")
   178  	c.Assert(aNetworker, gc.IsNil)
   179  }
   180  
   181  func (s *networkerSuite) TestMachineNetworkInfoPermissions(c *gc.C) {
   182  	args := params.Entities{Entities: []params.Entity{
   183  		{Tag: "service-bar"},
   184  		{Tag: "foo-42"},
   185  		{Tag: "unit-mysql-0"},
   186  		{Tag: "service-mysql"},
   187  		{Tag: "user-foo"},
   188  		{Tag: "machine-1"},
   189  		{Tag: "machine-0-lxc-42"},
   190  	}}
   191  	results, err := s.networker.MachineNetworkInfo(args)
   192  	c.Assert(err, gc.IsNil)
   193  	c.Assert(results, gc.DeepEquals, params.MachineNetworkInfoResults{
   194  		Results: []params.MachineNetworkInfoResult{
   195  			{Error: apiservertesting.ErrUnauthorized},
   196  			{Error: apiservertesting.ErrUnauthorized},
   197  			{Error: apiservertesting.ErrUnauthorized},
   198  			{Error: apiservertesting.ErrUnauthorized},
   199  			{Error: apiservertesting.ErrUnauthorized},
   200  			{Error: apiservertesting.ErrUnauthorized},
   201  			{Error: apiservertesting.NotFoundError("machine 0/lxc/42")},
   202  		},
   203  	})
   204  }
   205  
   206  func (s *networkerSuite) TestMachineNetworkInfo(c *gc.C) {
   207  	// Expected results of MachineNetworkInfo for a machine and containers
   208  	expectedMachineInfo := []network.Info{{
   209  		MACAddress:    "aa:bb:cc:dd:ee:f0",
   210  		CIDR:          "0.1.2.0/24",
   211  		NetworkName:   "net1",
   212  		ProviderId:    "net1",
   213  		VLANTag:       0,
   214  		InterfaceName: "eth0",
   215  	}, {
   216  		MACAddress:    "aa:bb:cc:dd:ee:f1",
   217  		CIDR:          "0.1.2.0/24",
   218  		NetworkName:   "net1",
   219  		ProviderId:    "net1",
   220  		VLANTag:       0,
   221  		InterfaceName: "eth1",
   222  	}, {
   223  		MACAddress:    "aa:bb:cc:dd:ee:f1",
   224  		CIDR:          "0.2.2.0/24",
   225  		NetworkName:   "vlan42",
   226  		ProviderId:    "vlan42",
   227  		VLANTag:       42,
   228  		InterfaceName: "eth1",
   229  	}, {
   230  		MACAddress:    "aa:bb:cc:dd:ee:f0",
   231  		CIDR:          "0.3.2.0/24",
   232  		NetworkName:   "vlan69",
   233  		ProviderId:    "vlan69",
   234  		VLANTag:       69,
   235  		InterfaceName: "eth0",
   236  	}, {
   237  		MACAddress:    "aa:bb:cc:dd:ee:f2",
   238  		CIDR:          "0.5.2.0/24",
   239  		NetworkName:   "net2",
   240  		ProviderId:    "net2",
   241  		VLANTag:       0,
   242  		InterfaceName: "eth2",
   243  	}}
   244  	expectedContainerInfo := []network.Info{{
   245  		MACAddress:    "aa:bb:cc:dd:ee:e0",
   246  		CIDR:          "0.1.2.0/24",
   247  		NetworkName:   "net1",
   248  		ProviderId:    "net1",
   249  		VLANTag:       0,
   250  		InterfaceName: "eth0",
   251  	}, {
   252  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   253  		CIDR:          "0.1.2.0/24",
   254  		NetworkName:   "net1",
   255  		ProviderId:    "net1",
   256  		VLANTag:       0,
   257  		InterfaceName: "eth1",
   258  	}, {
   259  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   260  		CIDR:          "0.2.2.0/24",
   261  		NetworkName:   "vlan42",
   262  		ProviderId:    "vlan42",
   263  		VLANTag:       42,
   264  		InterfaceName: "eth1",
   265  	}}
   266  	expectedNestedContainerInfo := []network.Info{{
   267  		MACAddress:    "aa:bb:cc:dd:ee:d0",
   268  		CIDR:          "0.1.2.0/24",
   269  		NetworkName:   "net1",
   270  		ProviderId:    "net1",
   271  		VLANTag:       0,
   272  		InterfaceName: "eth0",
   273  	}}
   274  
   275  	args := params.Entities{Entities: []params.Entity{
   276  		{Tag: "machine-0"},
   277  		{Tag: "machine-0-lxc-0"},
   278  		{Tag: "machine-0-lxc-0-lxc-0"},
   279  	}}
   280  	results, err := s.networker.MachineNetworkInfo(args)
   281  	c.Assert(err, gc.IsNil)
   282  	c.Assert(results, gc.DeepEquals, params.MachineNetworkInfoResults{
   283  		Results: []params.MachineNetworkInfoResult{
   284  			{Error: nil, Info: expectedMachineInfo},
   285  			{Error: nil, Info: expectedContainerInfo},
   286  			{Error: nil, Info: expectedNestedContainerInfo},
   287  		},
   288  	})
   289  }