github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/gce/environ_network_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package gce_test 5 6 import ( 7 "github.com/juju/errors" 8 jc "github.com/juju/testing/checkers" 9 "google.golang.org/api/compute/v1" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/core/instance" 13 "github.com/juju/juju/environs" 14 "github.com/juju/juju/environs/instances" 15 "github.com/juju/juju/network" 16 "github.com/juju/juju/provider/gce" 17 "github.com/juju/juju/provider/gce/google" 18 ) 19 20 type environNetSuite struct { 21 gce.BaseSuite 22 NetEnv environs.NetworkingEnviron 23 } 24 25 var _ = gc.Suite(&environNetSuite{}) 26 27 func (s *environNetSuite) SetUpTest(c *gc.C) { 28 s.BaseSuite.SetUpTest(c) 29 netEnv, ok := environs.SupportsNetworking(s.Env) 30 c.Assert(ok, jc.IsTrue) 31 s.NetEnv = netEnv 32 } 33 34 func (s *environNetSuite) cannedData() { 35 s.FakeConn.Zones = []google.AvailabilityZone{ 36 google.NewZone("a-zone", google.StatusUp, "", ""), 37 google.NewZone("b-zone", google.StatusUp, "", ""), 38 } 39 s.FakeConn.Networks_ = []*compute.Network{{ 40 Id: 9876, 41 Name: "go-team1", 42 AutoCreateSubnetworks: true, 43 SelfLink: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/go-team1", 44 Subnetworks: []string{ 45 "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1/subnetworks/go-team", 46 "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/us-central1/subnetworks/go-team", 47 }, 48 }, { 49 Id: 8765, 50 Name: "albini", 51 AutoCreateSubnetworks: false, 52 SelfLink: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/albini", 53 Subnetworks: []string{ 54 "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1/subnetworks/shellac", 55 "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/us-central1/subnetworks/flour", 56 }, 57 }, { 58 Id: 4567, 59 Name: "legacy", 60 AutoCreateSubnetworks: false, 61 IPv4Range: "10.240.0.0/16", 62 SelfLink: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/legacy", 63 }} 64 s.FakeConn.Subnets = []*compute.Subnetwork{{ 65 Id: 1234, 66 IpCidrRange: "10.0.10.0/24", 67 Name: "go-team", 68 Network: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/go-team1", 69 Region: "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1", 70 SelfLink: "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1/subnetworks/go-team", 71 }, { 72 Id: 1235, 73 IpCidrRange: "10.0.20.0/24", 74 Name: "shellac", 75 Network: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/albini", 76 Region: "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1", 77 SelfLink: "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1/subnetworks/shellac", 78 }} 79 } 80 81 func (s *environNetSuite) TestSubnetsInvalidCredentialError(c *gc.C) { 82 s.FakeConn.Err = gce.InvalidCredentialError 83 c.Assert(s.InvalidatedCredentials, jc.IsFalse) 84 _, err := s.NetEnv.Subnets(s.CallCtx, instance.UnknownId, nil) 85 c.Check(err, gc.NotNil) 86 c.Assert(s.InvalidatedCredentials, jc.IsTrue) 87 } 88 89 func (s *environNetSuite) TestGettingAllSubnets(c *gc.C) { 90 s.cannedData() 91 92 subnets, err := s.NetEnv.Subnets(s.CallCtx, instance.UnknownId, nil) 93 c.Assert(err, jc.ErrorIsNil) 94 95 c.Assert(subnets, gc.DeepEquals, []network.SubnetInfo{{ 96 ProviderId: "go-team", 97 ProviderNetworkId: "go-team1", 98 CIDR: "10.0.10.0/24", 99 AvailabilityZones: []string{"a-zone", "b-zone"}, 100 VLANTag: 0, 101 SpaceProviderId: "", 102 }, { 103 ProviderId: "shellac", 104 ProviderNetworkId: "albini", 105 CIDR: "10.0.20.0/24", 106 AvailabilityZones: []string{"a-zone", "b-zone"}, 107 VLANTag: 0, 108 SpaceProviderId: "", 109 }, { 110 ProviderId: "legacy", 111 ProviderNetworkId: "legacy", 112 CIDR: "10.240.0.0/16", 113 AvailabilityZones: []string{"a-zone", "b-zone"}, 114 VLANTag: 0, 115 SpaceProviderId: "", 116 }}) 117 } 118 119 func (s *environNetSuite) TestSuperSubnets(c *gc.C) { 120 s.cannedData() 121 122 subnets, err := s.NetEnv.SuperSubnets(s.CallCtx) 123 c.Assert(err, jc.ErrorIsNil) 124 125 c.Assert(subnets, gc.DeepEquals, []string{ 126 "10.0.10.0/24", 127 "10.0.20.0/24", 128 "10.240.0.0/16", 129 }) 130 } 131 132 func (s *environNetSuite) TestRestrictingToSubnets(c *gc.C) { 133 s.cannedData() 134 135 subnets, err := s.NetEnv.Subnets(s.CallCtx, instance.UnknownId, []network.Id{ 136 "shellac", 137 }) 138 c.Assert(err, jc.ErrorIsNil) 139 c.Assert(subnets, gc.DeepEquals, []network.SubnetInfo{{ 140 ProviderId: "shellac", 141 ProviderNetworkId: "albini", 142 CIDR: "10.0.20.0/24", 143 AvailabilityZones: []string{"a-zone", "b-zone"}, 144 VLANTag: 0, 145 SpaceProviderId: "", 146 }}) 147 } 148 149 func (s *environNetSuite) TestRestrictingToSubnetsWithMissing(c *gc.C) { 150 s.cannedData() 151 152 subnets, err := s.NetEnv.Subnets(s.CallCtx, instance.UnknownId, []network.Id{"shellac", "brunettes"}) 153 c.Assert(err, gc.ErrorMatches, `subnets \["brunettes"\] not found`) 154 c.Assert(err, jc.Satisfies, errors.IsNotFound) 155 c.Assert(subnets, gc.IsNil) 156 } 157 158 func (s *environNetSuite) TestSpecificInstance(c *gc.C) { 159 s.cannedData() 160 s.FakeEnviron.Insts = []instances.Instance{s.NewInstance(c, "moana")} 161 162 subnets, err := s.NetEnv.Subnets(s.CallCtx, instance.Id("moana"), nil) 163 c.Assert(err, jc.ErrorIsNil) 164 165 c.Assert(subnets, gc.DeepEquals, []network.SubnetInfo{{ 166 ProviderId: "go-team", 167 ProviderNetworkId: "go-team1", 168 CIDR: "10.0.10.0/24", 169 AvailabilityZones: []string{"a-zone", "b-zone"}, 170 VLANTag: 0, 171 SpaceProviderId: "", 172 }}) 173 } 174 175 func (s *environNetSuite) TestSpecificInstanceAndRestrictedSubnets(c *gc.C) { 176 s.cannedData() 177 s.FakeEnviron.Insts = []instances.Instance{s.NewInstance(c, "moana")} 178 179 subnets, err := s.NetEnv.Subnets(s.CallCtx, instance.Id("moana"), []network.Id{"go-team"}) 180 c.Assert(err, jc.ErrorIsNil) 181 182 c.Assert(subnets, gc.DeepEquals, []network.SubnetInfo{{ 183 ProviderId: "go-team", 184 ProviderNetworkId: "go-team1", 185 CIDR: "10.0.10.0/24", 186 AvailabilityZones: []string{"a-zone", "b-zone"}, 187 VLANTag: 0, 188 SpaceProviderId: "", 189 }}) 190 } 191 192 func (s *environNetSuite) TestSpecificInstanceAndRestrictedSubnetsWithMissing(c *gc.C) { 193 s.cannedData() 194 s.FakeEnviron.Insts = []instances.Instance{s.NewInstance(c, "moana")} 195 196 subnets, err := s.NetEnv.Subnets(s.CallCtx, instance.Id("moana"), []network.Id{"go-team", "shellac"}) 197 c.Assert(err, gc.ErrorMatches, `subnets \["shellac"\] not found`) 198 c.Assert(err, jc.Satisfies, errors.IsNotFound) 199 c.Assert(subnets, gc.IsNil) 200 } 201 202 func (s *environNetSuite) TestInterfaces(c *gc.C) { 203 s.cannedData() 204 s.FakeEnviron.Insts = []instances.Instance{s.NewInstance(c, "moana")} 205 206 infos, err := s.NetEnv.NetworkInterfaces(s.CallCtx, instance.Id("moana")) 207 c.Assert(err, jc.ErrorIsNil) 208 209 c.Assert(infos, gc.DeepEquals, []network.InterfaceInfo{{ 210 DeviceIndex: 0, 211 CIDR: "10.0.10.0/24", 212 ProviderId: "moana/somenetif", 213 ProviderSubnetId: "go-team", 214 ProviderNetworkId: "go-team1", 215 AvailabilityZones: []string{"a-zone", "b-zone"}, 216 InterfaceName: "somenetif", 217 InterfaceType: network.EthernetInterface, 218 Disabled: false, 219 NoAutoStart: false, 220 ConfigType: network.ConfigDHCP, 221 Address: network.NewScopedAddress("10.0.10.3", network.ScopeCloudLocal), 222 }}) 223 } 224 225 func (s *environNetSuite) TestNetworkInterfaceInvalidCredentialError(c *gc.C) { 226 s.FakeConn.Err = gce.InvalidCredentialError 227 c.Assert(s.InvalidatedCredentials, jc.IsFalse) 228 s.cannedData() 229 baseInst := s.NewBaseInstance(c, "moana") 230 // This isn't possible in GCE at the moment, but we don't want to 231 // break when it is. 232 summary := &baseInst.InstanceSummary 233 summary.NetworkInterfaces = append(summary.NetworkInterfaces, &compute.NetworkInterface{ 234 Name: "othernetif", 235 NetworkIP: "10.0.20.3", 236 Network: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/shellac", 237 Subnetwork: "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1/subnetworks/shellac", 238 AccessConfigs: []*compute.AccessConfig{{ 239 Type: "ONE_TO_ONE_NAT", 240 Name: "ExternalNAT", 241 NatIP: "25.185.142.227", 242 }}, 243 }) 244 s.FakeEnviron.Insts = []instances.Instance{s.NewInstanceFromBase(baseInst)} 245 246 _, err := s.NetEnv.NetworkInterfaces(s.CallCtx, instance.Id("moana")) 247 c.Check(err, gc.NotNil) 248 c.Assert(s.InvalidatedCredentials, jc.IsTrue) 249 } 250 251 func (s *environNetSuite) TestInterfacesMulti(c *gc.C) { 252 s.cannedData() 253 baseInst := s.NewBaseInstance(c, "moana") 254 // This isn't possible in GCE at the moment, but we don't want to 255 // break when it is. 256 summary := &baseInst.InstanceSummary 257 summary.NetworkInterfaces = append(summary.NetworkInterfaces, &compute.NetworkInterface{ 258 Name: "othernetif", 259 NetworkIP: "10.0.20.3", 260 Network: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/shellac", 261 Subnetwork: "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1/subnetworks/shellac", 262 AccessConfigs: []*compute.AccessConfig{{ 263 Type: "ONE_TO_ONE_NAT", 264 Name: "ExternalNAT", 265 NatIP: "25.185.142.227", 266 }}, 267 }) 268 s.FakeEnviron.Insts = []instances.Instance{s.NewInstanceFromBase(baseInst)} 269 270 infos, err := s.NetEnv.NetworkInterfaces(s.CallCtx, instance.Id("moana")) 271 c.Assert(err, jc.ErrorIsNil) 272 273 c.Assert(infos, gc.DeepEquals, []network.InterfaceInfo{{ 274 DeviceIndex: 0, 275 CIDR: "10.0.10.0/24", 276 ProviderId: "moana/somenetif", 277 ProviderSubnetId: "go-team", 278 ProviderNetworkId: "go-team1", 279 AvailabilityZones: []string{"a-zone", "b-zone"}, 280 InterfaceName: "somenetif", 281 InterfaceType: network.EthernetInterface, 282 Disabled: false, 283 NoAutoStart: false, 284 ConfigType: network.ConfigDHCP, 285 Address: network.NewScopedAddress("10.0.10.3", network.ScopeCloudLocal), 286 }, { 287 DeviceIndex: 1, 288 CIDR: "10.0.20.0/24", 289 ProviderId: "moana/othernetif", 290 ProviderSubnetId: "shellac", 291 ProviderNetworkId: "albini", 292 AvailabilityZones: []string{"a-zone", "b-zone"}, 293 InterfaceName: "othernetif", 294 InterfaceType: network.EthernetInterface, 295 Disabled: false, 296 NoAutoStart: false, 297 ConfigType: network.ConfigDHCP, 298 Address: network.NewScopedAddress("10.0.20.3", network.ScopeCloudLocal), 299 }}) 300 } 301 302 func (s *environNetSuite) TestInterfacesLegacy(c *gc.C) { 303 s.cannedData() 304 baseInst := s.NewBaseInstance(c, "moana") 305 // When we're using a legacy network there'll be no subnet. 306 summary := &baseInst.InstanceSummary 307 summary.NetworkInterfaces = []*compute.NetworkInterface{{ 308 Name: "somenetif", 309 NetworkIP: "10.240.0.2", 310 Network: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/legacy", 311 Subnetwork: "", 312 AccessConfigs: []*compute.AccessConfig{{ 313 Type: "ONE_TO_ONE_NAT", 314 Name: "ExternalNAT", 315 NatIP: "25.185.142.227", 316 }}, 317 }} 318 s.FakeEnviron.Insts = []instances.Instance{s.NewInstanceFromBase(baseInst)} 319 320 infos, err := s.NetEnv.NetworkInterfaces(s.CallCtx, instance.Id("moana")) 321 c.Assert(err, jc.ErrorIsNil) 322 323 c.Assert(infos, gc.DeepEquals, []network.InterfaceInfo{{ 324 DeviceIndex: 0, 325 CIDR: "10.240.0.0/16", 326 ProviderId: "moana/somenetif", 327 ProviderSubnetId: "", 328 ProviderNetworkId: "legacy", 329 AvailabilityZones: []string{"a-zone", "b-zone"}, 330 InterfaceName: "somenetif", 331 InterfaceType: network.EthernetInterface, 332 Disabled: false, 333 NoAutoStart: false, 334 ConfigType: network.ConfigDHCP, 335 Address: network.NewScopedAddress("10.240.0.2", network.ScopeCloudLocal), 336 }}) 337 } 338 339 func (s *environNetSuite) TestInterfacesSameSubnetwork(c *gc.C) { 340 s.cannedData() 341 baseInst := s.NewBaseInstance(c, "moana") 342 // This isn't possible in GCE at the moment, but we don't want to 343 // break when it is. 344 summary := &baseInst.InstanceSummary 345 summary.NetworkInterfaces = append(summary.NetworkInterfaces, &compute.NetworkInterface{ 346 Name: "othernetif", 347 NetworkIP: "10.0.10.4", 348 Network: "https://www.googleapis.com/compute/v1/projects/sonic-youth/global/networks/go-team1", 349 Subnetwork: "https://www.googleapis.com/compute/v1/projects/sonic-youth/regions/asia-east1/subnetworks/go-team", 350 AccessConfigs: []*compute.AccessConfig{{ 351 Type: "ONE_TO_ONE_NAT", 352 Name: "ExternalNAT", 353 NatIP: "25.185.142.227", 354 }}, 355 }) 356 s.FakeEnviron.Insts = []instances.Instance{s.NewInstanceFromBase(baseInst)} 357 358 infos, err := s.NetEnv.NetworkInterfaces(s.CallCtx, instance.Id("moana")) 359 c.Assert(err, jc.ErrorIsNil) 360 361 c.Assert(infos, gc.DeepEquals, []network.InterfaceInfo{{ 362 DeviceIndex: 0, 363 CIDR: "10.0.10.0/24", 364 ProviderId: "moana/somenetif", 365 ProviderSubnetId: "go-team", 366 ProviderNetworkId: "go-team1", 367 AvailabilityZones: []string{"a-zone", "b-zone"}, 368 InterfaceName: "somenetif", 369 InterfaceType: network.EthernetInterface, 370 Disabled: false, 371 NoAutoStart: false, 372 ConfigType: network.ConfigDHCP, 373 Address: network.NewScopedAddress("10.0.10.3", network.ScopeCloudLocal), 374 }, { 375 DeviceIndex: 1, 376 CIDR: "10.0.10.0/24", 377 ProviderId: "moana/othernetif", 378 ProviderSubnetId: "go-team", 379 ProviderNetworkId: "go-team1", 380 AvailabilityZones: []string{"a-zone", "b-zone"}, 381 InterfaceName: "othernetif", 382 InterfaceType: network.EthernetInterface, 383 Disabled: false, 384 NoAutoStart: false, 385 ConfigType: network.ConfigDHCP, 386 Address: network.NewScopedAddress("10.0.10.4", network.ScopeCloudLocal), 387 }}) 388 }