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  }