github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/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  	"github.com/juju/names"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  
    11  	"github.com/juju/juju/apiserver/common"
    12  	"github.com/juju/juju/apiserver/networker"
    13  	"github.com/juju/juju/apiserver/params"
    14  	apiservertesting "github.com/juju/juju/apiserver/testing"
    15  	"github.com/juju/juju/instance"
    16  	"github.com/juju/juju/juju/testing"
    17  	"github.com/juju/juju/state"
    18  	statetesting "github.com/juju/juju/state/testing"
    19  )
    20  
    21  type networkerSuite struct {
    22  	testing.JujuConnSuite
    23  
    24  	networks []state.NetworkInfo
    25  
    26  	machine         *state.Machine
    27  	container       *state.Machine
    28  	nestedContainer *state.Machine
    29  
    30  	machineIfaces         []state.NetworkInterfaceInfo
    31  	containerIfaces       []state.NetworkInterfaceInfo
    32  	nestedContainerIfaces []state.NetworkInterfaceInfo
    33  
    34  	authorizer apiservertesting.FakeAuthorizer
    35  	resources  *common.Resources
    36  	networker  *networker.NetworkerAPI
    37  }
    38  
    39  var _ = gc.Suite(&networkerSuite{})
    40  
    41  // Create several networks.
    42  func (s *networkerSuite) setUpNetworks(c *gc.C) {
    43  	s.networks = []state.NetworkInfo{{
    44  		Name:       "net1",
    45  		ProviderId: "net1",
    46  		CIDR:       "0.1.2.0/24",
    47  		VLANTag:    0,
    48  	}, {
    49  		Name:       "vlan42",
    50  		ProviderId: "vlan42",
    51  		CIDR:       "0.2.2.0/24",
    52  		VLANTag:    42,
    53  	}, {
    54  		Name:       "vlan69",
    55  		ProviderId: "vlan69",
    56  		CIDR:       "0.3.2.0/24",
    57  		VLANTag:    69,
    58  	}, {
    59  		Name:       "vlan123",
    60  		ProviderId: "vlan123",
    61  		CIDR:       "0.4.2.0/24",
    62  		VLANTag:    123,
    63  	}, {
    64  		Name:       "net2",
    65  		ProviderId: "net2",
    66  		CIDR:       "0.5.2.0/24",
    67  		VLANTag:    0,
    68  	}}
    69  }
    70  
    71  // Create a machine to use.
    72  func (s *networkerSuite) setUpMachine(c *gc.C) {
    73  	var err error
    74  	s.machine, err = s.State.AddMachine("quantal", state.JobHostUnits)
    75  	c.Assert(err, jc.ErrorIsNil)
    76  	hwChars := instance.MustParseHardware("arch=i386", "mem=4G")
    77  	s.machineIfaces = []state.NetworkInterfaceInfo{{
    78  		MACAddress:    "aa:bb:cc:dd:ee:f0",
    79  		InterfaceName: "eth0",
    80  		NetworkName:   "net1",
    81  		IsVirtual:     false,
    82  	}, {
    83  		MACAddress:    "aa:bb:cc:dd:ee:f1",
    84  		InterfaceName: "eth1",
    85  		NetworkName:   "net1",
    86  		IsVirtual:     false,
    87  	}, {
    88  		MACAddress:    "aa:bb:cc:dd:ee:f1",
    89  		InterfaceName: "eth1.42",
    90  		NetworkName:   "vlan42",
    91  		IsVirtual:     true,
    92  	}, {
    93  		MACAddress:    "aa:bb:cc:dd:ee:f0",
    94  		InterfaceName: "eth0.69",
    95  		NetworkName:   "vlan69",
    96  		IsVirtual:     true,
    97  	}, {
    98  		MACAddress:    "aa:bb:cc:dd:ee:f2",
    99  		InterfaceName: "eth2",
   100  		NetworkName:   "net2",
   101  		IsVirtual:     false,
   102  		Disabled:      true,
   103  	}}
   104  	err = s.machine.SetInstanceInfo("i-am", "fake_nonce", &hwChars, s.networks, s.machineIfaces, nil)
   105  	c.Assert(err, jc.ErrorIsNil)
   106  }
   107  
   108  // Create and provision a container and a nested container.
   109  func (s *networkerSuite) setUpContainers(c *gc.C) {
   110  	template := state.MachineTemplate{
   111  		Series: "quantal",
   112  		Jobs:   []state.MachineJob{state.JobHostUnits},
   113  	}
   114  	var err error
   115  	s.container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC)
   116  	c.Assert(err, jc.ErrorIsNil)
   117  	s.containerIfaces = []state.NetworkInterfaceInfo{{
   118  		MACAddress:    "aa:bb:cc:dd:ee:e0",
   119  		InterfaceName: "eth0",
   120  		NetworkName:   "net1",
   121  		IsVirtual:     false,
   122  	}, {
   123  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   124  		InterfaceName: "eth1",
   125  		NetworkName:   "net1",
   126  		IsVirtual:     false,
   127  	}, {
   128  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   129  		InterfaceName: "eth1.42",
   130  		NetworkName:   "vlan42",
   131  		IsVirtual:     true,
   132  	}}
   133  	hwChars := instance.MustParseHardware("arch=i386", "mem=4G")
   134  	err = s.container.SetInstanceInfo("i-container", "fake_nonce", &hwChars, s.networks[:2],
   135  		s.containerIfaces, nil)
   136  	c.Assert(err, jc.ErrorIsNil)
   137  
   138  	s.nestedContainer, err = s.State.AddMachineInsideMachine(template, s.container.Id(), instance.LXC)
   139  	c.Assert(err, jc.ErrorIsNil)
   140  	s.nestedContainerIfaces = []state.NetworkInterfaceInfo{{
   141  		MACAddress:    "aa:bb:cc:dd:ee:d0",
   142  		InterfaceName: "eth0",
   143  		NetworkName:   "net1",
   144  	}}
   145  	err = s.nestedContainer.SetInstanceInfo("i-too", "fake_nonce", &hwChars, s.networks[:1],
   146  		s.nestedContainerIfaces, nil)
   147  	c.Assert(err, jc.ErrorIsNil)
   148  }
   149  
   150  func (s *networkerSuite) SetUpTest(c *gc.C) {
   151  	s.JujuConnSuite.SetUpTest(c)
   152  
   153  	s.setUpNetworks(c)
   154  	s.setUpMachine(c)
   155  	s.setUpContainers(c)
   156  
   157  	// Create a FakeAuthorizer so we can check permissions,
   158  	// set up assuming we logged in as a machine agent.
   159  	s.authorizer = apiservertesting.FakeAuthorizer{
   160  		Tag: s.machine.Tag(),
   161  	}
   162  
   163  	// Create the resource registry separately to track invocations to
   164  	// Register.
   165  	s.resources = common.NewResources()
   166  
   167  	// Create a networker API for the machine.
   168  	var err error
   169  	s.networker, err = networker.NewNetworkerAPI(
   170  		s.State,
   171  		s.resources,
   172  		s.authorizer,
   173  	)
   174  	c.Assert(err, jc.ErrorIsNil)
   175  }
   176  
   177  func (s *networkerSuite) TestNetworkerNonMachineAgent(c *gc.C) {
   178  	// Fails with not a machine agent
   179  	anAuthorizer := s.authorizer
   180  	anAuthorizer.Tag = names.NewUnitTag("ubuntu/1")
   181  	aNetworker, err := networker.NewNetworkerAPI(s.State, s.resources, anAuthorizer)
   182  	c.Assert(err, gc.ErrorMatches, "permission denied")
   183  	c.Assert(aNetworker, gc.IsNil)
   184  }
   185  
   186  func (s *networkerSuite) TestMachineNetworkInfoPermissions(c *gc.C) {
   187  	args := params.Entities{Entities: []params.Entity{
   188  		{Tag: "service-bar"},
   189  		{Tag: "foo-42"},
   190  		{Tag: "unit-mysql-0"},
   191  		{Tag: "service-mysql"},
   192  		{Tag: "user-foo"},
   193  		{Tag: "machine-1"},
   194  		{Tag: "machine-0-lxc-42"},
   195  	}}
   196  	results, err := s.networker.MachineNetworkInfo(args)
   197  	c.Assert(err, jc.ErrorIsNil)
   198  	c.Assert(results, gc.DeepEquals, params.MachineNetworkInfoResults{
   199  		Results: []params.MachineNetworkInfoResult{
   200  			{Error: apiservertesting.ErrUnauthorized},
   201  			{Error: apiservertesting.ErrUnauthorized},
   202  			{Error: apiservertesting.ErrUnauthorized},
   203  			{Error: apiservertesting.ErrUnauthorized},
   204  			{Error: apiservertesting.ErrUnauthorized},
   205  			{Error: apiservertesting.ErrUnauthorized},
   206  			{Error: apiservertesting.NotFoundError("machine 0/lxc/42")},
   207  		},
   208  	})
   209  }
   210  
   211  func (s *networkerSuite) TestMachineNetworkInfo(c *gc.C) {
   212  	// Expected results of MachineNetworkInfo for a machine and containers
   213  	expectedMachineInfo := []params.NetworkInfo{{
   214  		MACAddress:    "aa:bb:cc:dd:ee:f0",
   215  		CIDR:          "0.1.2.0/24",
   216  		NetworkName:   "net1",
   217  		ProviderId:    "net1",
   218  		VLANTag:       0,
   219  		InterfaceName: "eth0",
   220  	}, {
   221  		MACAddress:    "aa:bb:cc:dd:ee:f1",
   222  		CIDR:          "0.1.2.0/24",
   223  		NetworkName:   "net1",
   224  		ProviderId:    "net1",
   225  		VLANTag:       0,
   226  		InterfaceName: "eth1",
   227  	}, {
   228  		MACAddress:    "aa:bb:cc:dd:ee:f1",
   229  		CIDR:          "0.2.2.0/24",
   230  		NetworkName:   "vlan42",
   231  		ProviderId:    "vlan42",
   232  		VLANTag:       42,
   233  		InterfaceName: "eth1",
   234  	}, {
   235  		MACAddress:    "aa:bb:cc:dd:ee:f0",
   236  		CIDR:          "0.3.2.0/24",
   237  		NetworkName:   "vlan69",
   238  		ProviderId:    "vlan69",
   239  		VLANTag:       69,
   240  		InterfaceName: "eth0",
   241  	}, {
   242  		MACAddress:    "aa:bb:cc:dd:ee:f2",
   243  		CIDR:          "0.5.2.0/24",
   244  		NetworkName:   "net2",
   245  		ProviderId:    "net2",
   246  		VLANTag:       0,
   247  		InterfaceName: "eth2",
   248  		Disabled:      true,
   249  	}}
   250  	expectedContainerInfo := []params.NetworkInfo{{
   251  		MACAddress:    "aa:bb:cc:dd:ee:e0",
   252  		CIDR:          "0.1.2.0/24",
   253  		NetworkName:   "net1",
   254  		ProviderId:    "net1",
   255  		VLANTag:       0,
   256  		InterfaceName: "eth0",
   257  	}, {
   258  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   259  		CIDR:          "0.1.2.0/24",
   260  		NetworkName:   "net1",
   261  		ProviderId:    "net1",
   262  		VLANTag:       0,
   263  		InterfaceName: "eth1",
   264  	}, {
   265  		MACAddress:    "aa:bb:cc:dd:ee:e1",
   266  		CIDR:          "0.2.2.0/24",
   267  		NetworkName:   "vlan42",
   268  		ProviderId:    "vlan42",
   269  		VLANTag:       42,
   270  		InterfaceName: "eth1",
   271  	}}
   272  	expectedNestedContainerInfo := []params.NetworkInfo{{
   273  		MACAddress:    "aa:bb:cc:dd:ee:d0",
   274  		CIDR:          "0.1.2.0/24",
   275  		NetworkName:   "net1",
   276  		ProviderId:    "net1",
   277  		VLANTag:       0,
   278  		InterfaceName: "eth0",
   279  	}}
   280  
   281  	args := params.Entities{Entities: []params.Entity{
   282  		{Tag: "machine-0"},
   283  		{Tag: "machine-0-lxc-0"},
   284  		{Tag: "machine-0-lxc-0-lxc-0"},
   285  	}}
   286  	results, err := s.networker.MachineNetworkInfo(args)
   287  	c.Assert(err, jc.ErrorIsNil)
   288  	c.Assert(results, gc.DeepEquals, params.MachineNetworkInfoResults{
   289  		Results: []params.MachineNetworkInfoResult{
   290  			{Error: nil, Info: expectedMachineInfo},
   291  			{Error: nil, Info: expectedContainerInfo},
   292  			{Error: nil, Info: expectedNestedContainerInfo},
   293  		},
   294  	})
   295  }
   296  
   297  func (s *networkerSuite) TestWatchInterfacesPermissions(c *gc.C) {
   298  	args := params.Entities{Entities: []params.Entity{
   299  		{Tag: "service-bar"},
   300  		{Tag: "foo-42"},
   301  		{Tag: "unit-mysql-0"},
   302  		{Tag: "service-mysql"},
   303  		{Tag: "user-foo"},
   304  		{Tag: "machine-1"},
   305  		{Tag: "machine-0-lxc-42"},
   306  	}}
   307  	results, err := s.networker.WatchInterfaces(args)
   308  	c.Assert(err, jc.ErrorIsNil)
   309  	c.Assert(results, gc.DeepEquals, params.NotifyWatchResults{
   310  		Results: []params.NotifyWatchResult{
   311  			{Error: apiservertesting.ErrUnauthorized},
   312  			{Error: apiservertesting.ErrUnauthorized},
   313  			{Error: apiservertesting.ErrUnauthorized},
   314  			{Error: apiservertesting.ErrUnauthorized},
   315  			{Error: apiservertesting.ErrUnauthorized},
   316  			{Error: apiservertesting.ErrUnauthorized},
   317  			{Error: apiservertesting.NotFoundError("machine 0/lxc/42")},
   318  		},
   319  	})
   320  }
   321  
   322  func (s *networkerSuite) TestWatchInterfaces(c *gc.C) {
   323  	c.Assert(s.resources.Count(), gc.Equals, 0)
   324  
   325  	args := params.Entities{Entities: []params.Entity{
   326  		{Tag: "machine-0"},
   327  		{Tag: "machine-0-lxc-0"},
   328  		{Tag: "machine-0-lxc-0-lxc-0"},
   329  	}}
   330  	result, err := s.networker.WatchInterfaces(args)
   331  	c.Assert(err, jc.ErrorIsNil)
   332  	c.Assert(result, gc.DeepEquals, params.NotifyWatchResults{
   333  		Results: []params.NotifyWatchResult{
   334  			{NotifyWatcherId: "1"},
   335  			{NotifyWatcherId: "2"},
   336  			{NotifyWatcherId: "3"},
   337  		},
   338  	})
   339  
   340  	// Verify the resource was registered and stop when done
   341  	c.Assert(s.resources.Count(), gc.Equals, 3)
   342  	for _, watcherId := range []string{"1", "2", "3"} {
   343  		resource := s.resources.Get(watcherId)
   344  		defer statetesting.AssertStop(c, resource)
   345  
   346  		// Check that the WatchInterfaces has consumed the initial event ("returned" in
   347  		// the Watch call)
   348  		wc := statetesting.NewNotifyWatcherC(c, s.State, resource.(state.NotifyWatcher))
   349  		wc.AssertNoChange()
   350  	}
   351  }