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 }