github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/gce/google/conn_network_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package google_test
     5  
     6  import (
     7  	"regexp"
     8  	"sort"
     9  
    10  	"github.com/juju/collections/set"
    11  	"github.com/juju/errors"
    12  	jc "github.com/juju/testing/checkers"
    13  	"google.golang.org/api/compute/v1"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/core/network"
    17  	corefirewall "github.com/juju/juju/core/network/firewall"
    18  	"github.com/juju/juju/provider/gce/google"
    19  )
    20  
    21  func (s *connSuite) TestConnectionIngressRules(c *gc.C) {
    22  	s.FakeConn.Firewalls = []*compute.Firewall{{
    23  		Name:         "spam",
    24  		TargetTags:   []string{"spam"},
    25  		SourceRanges: []string{"10.0.0.0/24", "192.168.1.0/24"},
    26  		Allowed: []*compute.FirewallAllowed{
    27  			{
    28  				IPProtocol: "tcp",
    29  				Ports:      []string{"80-81", "92"},
    30  			}, {
    31  				IPProtocol: "udp",
    32  				Ports:      []string{"443", "100-120"},
    33  			},
    34  		},
    35  	}}
    36  
    37  	ports, err := s.Conn.IngressRules("spam")
    38  	c.Assert(err, jc.ErrorIsNil)
    39  	c.Check(
    40  		ports, jc.DeepEquals,
    41  		corefirewall.IngressRules{
    42  			corefirewall.NewIngressRule(network.MustParsePortRange("80-81/tcp"), "10.0.0.0/24", "192.168.1.0/24"),
    43  			corefirewall.NewIngressRule(network.MustParsePortRange("92/tcp"), "10.0.0.0/24", "192.168.1.0/24"),
    44  			corefirewall.NewIngressRule(network.MustParsePortRange("100-120/udp"), "10.0.0.0/24", "192.168.1.0/24"),
    45  			corefirewall.NewIngressRule(network.MustParsePortRange("443/udp"), "10.0.0.0/24", "192.168.1.0/24"),
    46  		},
    47  	)
    48  }
    49  
    50  func (s *connSuite) TestConnectionIngressRulesCollapse(c *gc.C) {
    51  	s.FakeConn.Firewalls = []*compute.Firewall{{
    52  		Name:         "spam",
    53  		TargetTags:   []string{"spam"},
    54  		SourceRanges: []string{"10.0.0.0/24", "192.168.1.0/24"},
    55  		Allowed: []*compute.FirewallAllowed{{
    56  			IPProtocol: "tcp",
    57  			Ports:      []string{"81"},
    58  		}, {
    59  			IPProtocol: "tcp",
    60  			Ports:      []string{"82"},
    61  		}, {
    62  			IPProtocol: "tcp",
    63  			Ports:      []string{"80"},
    64  		}, {
    65  			IPProtocol: "tcp",
    66  			Ports:      []string{"83"},
    67  		}, {
    68  			IPProtocol: "tcp",
    69  			Ports:      []string{"92"},
    70  		}},
    71  	}}
    72  
    73  	ports, err := s.Conn.IngressRules("spam")
    74  	c.Assert(err, jc.ErrorIsNil)
    75  	c.Check(
    76  		ports, jc.DeepEquals,
    77  		corefirewall.IngressRules{
    78  			corefirewall.NewIngressRule(network.MustParsePortRange("80-83/tcp"), "10.0.0.0/24", "192.168.1.0/24"),
    79  			corefirewall.NewIngressRule(network.MustParsePortRange("92/tcp"), "10.0.0.0/24", "192.168.1.0/24"),
    80  		},
    81  	)
    82  }
    83  
    84  func (s *connSuite) TestConnectionIngressRulesDefaultCIDR(c *gc.C) {
    85  	s.FakeConn.Firewalls = []*compute.Firewall{{
    86  		Name:       "spam",
    87  		TargetTags: []string{"spam"},
    88  		Allowed: []*compute.FirewallAllowed{{
    89  			IPProtocol: "tcp",
    90  			Ports:      []string{"80-81", "92"},
    91  		}},
    92  	}}
    93  
    94  	ports, err := s.Conn.IngressRules("spam")
    95  	c.Assert(err, jc.ErrorIsNil)
    96  	c.Check(
    97  		ports, jc.DeepEquals,
    98  		corefirewall.IngressRules{
    99  			corefirewall.NewIngressRule(network.MustParsePortRange("80-81/tcp"), corefirewall.AllNetworksIPV4CIDR),
   100  			corefirewall.NewIngressRule(network.MustParsePortRange("92/tcp"), corefirewall.AllNetworksIPV4CIDR),
   101  		},
   102  	)
   103  }
   104  
   105  func (s *connSuite) TestConnectionPortsAPI(c *gc.C) {
   106  	s.FakeConn.Firewalls = []*compute.Firewall{{
   107  		Name:         "spam",
   108  		TargetTags:   []string{"spam"},
   109  		SourceRanges: []string{"0.0.0.0/0"},
   110  		Allowed: []*compute.FirewallAllowed{{
   111  			IPProtocol: "tcp",
   112  			Ports:      []string{"80-81"},
   113  		}},
   114  	}}
   115  
   116  	_, err := s.Conn.IngressRules("eggs")
   117  	c.Assert(err, jc.ErrorIsNil)
   118  
   119  	c.Check(s.FakeConn.Calls, gc.HasLen, 1)
   120  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   121  	c.Check(s.FakeConn.Calls[0].ProjectID, gc.Equals, "spam")
   122  	c.Check(s.FakeConn.Calls[0].Name, gc.Equals, "eggs")
   123  }
   124  
   125  func (s *connSuite) TestConnectionOpenPortsAdd(c *gc.C) {
   126  	s.FakeConn.Err = errors.NotFoundf("spam")
   127  
   128  	rules := corefirewall.IngressRules{
   129  		corefirewall.NewIngressRule(network.MustParsePortRange("80-81/tcp")), // leave out CIDR to check default
   130  		corefirewall.NewIngressRule(network.MustParsePortRange("80-81/udp"), corefirewall.AllNetworksIPV4CIDR),
   131  		corefirewall.NewIngressRule(network.MustParsePortRange("100-120/tcp"), "192.168.1.0/24", "10.0.0.0/24"),
   132  		corefirewall.NewIngressRule(network.MustParsePortRange("67/udp"), "10.0.0.0/24"),
   133  	}
   134  	err := s.Conn.OpenPortsWithNamer("spam", google.HashSuffixNamer, rules)
   135  	c.Assert(err, jc.ErrorIsNil)
   136  
   137  	c.Check(s.FakeConn.Calls, gc.HasLen, 4)
   138  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   139  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "AddFirewall")
   140  	c.Check(s.FakeConn.Calls[1].Firewall, jc.DeepEquals, &compute.Firewall{
   141  		Name:         "spam-4eebe8d7a9",
   142  		TargetTags:   []string{"spam"},
   143  		SourceRanges: []string{"10.0.0.0/24", "192.168.1.0/24"},
   144  		Allowed: []*compute.FirewallAllowed{{
   145  			IPProtocol: "tcp",
   146  			Ports:      []string{"100-120"},
   147  		}},
   148  	})
   149  	c.Check(s.FakeConn.Calls[2].FuncName, gc.Equals, "AddFirewall")
   150  	c.Check(s.FakeConn.Calls[2].Firewall, jc.DeepEquals, &compute.Firewall{
   151  		Name:         "spam-a34d80f7b6",
   152  		TargetTags:   []string{"spam"},
   153  		SourceRanges: []string{"10.0.0.0/24"},
   154  		Allowed: []*compute.FirewallAllowed{{
   155  			IPProtocol: "udp",
   156  			Ports:      []string{"67"},
   157  		}},
   158  	})
   159  	c.Check(s.FakeConn.Calls[3].FuncName, gc.Equals, "AddFirewall")
   160  	c.Check(s.FakeConn.Calls[3].Firewall, jc.DeepEquals, &compute.Firewall{
   161  		Name:         "spam",
   162  		TargetTags:   []string{"spam"},
   163  		SourceRanges: []string{"0.0.0.0/0"},
   164  		Allowed: []*compute.FirewallAllowed{{
   165  			IPProtocol: "tcp",
   166  			Ports:      []string{"80-81"},
   167  		}, {
   168  			IPProtocol: "udp",
   169  			Ports:      []string{"80-81"},
   170  		}},
   171  	})
   172  }
   173  
   174  func (s *connSuite) TestConnectionOpenPortsUpdateSameCIDR(c *gc.C) {
   175  	s.FakeConn.Firewalls = []*compute.Firewall{{
   176  		Name:         "spam-ad7554",
   177  		TargetTags:   []string{"spam"},
   178  		SourceRanges: []string{"192.168.1.0/24", "10.0.0.0/24"},
   179  		Allowed: []*compute.FirewallAllowed{{
   180  			IPProtocol: "tcp",
   181  			Ports:      []string{"80-81"},
   182  		}},
   183  	}}
   184  
   185  	rules := corefirewall.IngressRules{
   186  		corefirewall.NewIngressRule(network.MustParsePortRange("443/tcp"), "192.168.1.0/24", "10.0.0.0/24"),
   187  	}
   188  	err := s.Conn.OpenPortsWithNamer("spam", google.HashSuffixNamer, rules)
   189  	c.Assert(err, jc.ErrorIsNil)
   190  
   191  	c.Check(s.FakeConn.Calls, gc.HasLen, 2)
   192  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   193  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "UpdateFirewall")
   194  	sort.Strings(s.FakeConn.Calls[1].Firewall.Allowed[0].Ports)
   195  	c.Check(s.FakeConn.Calls[1].Firewall, jc.DeepEquals, &compute.Firewall{
   196  		Name:         "spam-ad7554",
   197  		TargetTags:   []string{"spam"},
   198  		SourceRanges: []string{"10.0.0.0/24", "192.168.1.0/24"},
   199  		Allowed: []*compute.FirewallAllowed{{
   200  			IPProtocol: "tcp",
   201  			Ports:      []string{"443", "80-81"},
   202  		}},
   203  	})
   204  }
   205  
   206  func (s *connSuite) TestConnectionOpenPortsUpdateAddCIDR(c *gc.C) {
   207  	s.FakeConn.Firewalls = []*compute.Firewall{{
   208  		Name:         "spam-arbitrary-name",
   209  		TargetTags:   []string{"spam"},
   210  		SourceRanges: []string{"192.168.1.0/24"},
   211  		Allowed: []*compute.FirewallAllowed{{
   212  			IPProtocol: "tcp",
   213  			Ports:      []string{"80-81"},
   214  		}},
   215  	}}
   216  
   217  	rules := corefirewall.IngressRules{
   218  		corefirewall.NewIngressRule(network.MustParsePortRange("80-81/tcp"), "10.0.0.0/24"),
   219  	}
   220  	err := s.Conn.OpenPortsWithNamer("spam", google.HashSuffixNamer, rules)
   221  	c.Assert(err, jc.ErrorIsNil)
   222  
   223  	c.Check(s.FakeConn.Calls, gc.HasLen, 2)
   224  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   225  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "UpdateFirewall")
   226  	sort.Strings(s.FakeConn.Calls[1].Firewall.Allowed[0].Ports)
   227  	c.Check(s.FakeConn.Calls[1].Name, gc.Equals, "spam-arbitrary-name")
   228  	c.Check(s.FakeConn.Calls[1].Firewall, jc.DeepEquals, &compute.Firewall{
   229  		Name:         "spam-arbitrary-name",
   230  		TargetTags:   []string{"spam"},
   231  		SourceRanges: []string{"10.0.0.0/24", "192.168.1.0/24"},
   232  		Allowed: []*compute.FirewallAllowed{{
   233  			IPProtocol: "tcp",
   234  			Ports:      []string{"80-81"},
   235  		}},
   236  	})
   237  }
   238  
   239  func (s *connSuite) TestConnectionOpenPortsUpdateAndAdd(c *gc.C) {
   240  	s.FakeConn.Firewalls = []*compute.Firewall{{
   241  		Name:         "spam-d01a82",
   242  		TargetTags:   []string{"spam"},
   243  		SourceRanges: []string{"192.168.1.0/24"},
   244  		Allowed: []*compute.FirewallAllowed{{
   245  			IPProtocol: "tcp",
   246  			Ports:      []string{"80-81"},
   247  		}},
   248  	}, {
   249  		Name:         "spam-8e65efabcd",
   250  		TargetTags:   []string{"spam"},
   251  		SourceRanges: []string{"172.0.0.0/24"},
   252  		Allowed: []*compute.FirewallAllowed{{
   253  			IPProtocol: "tcp",
   254  			Ports:      []string{"100-120", "443"},
   255  		}},
   256  	}}
   257  
   258  	rules := corefirewall.IngressRules{
   259  		corefirewall.NewIngressRule(network.MustParsePortRange("443/tcp"), "192.168.1.0/24"),
   260  		corefirewall.NewIngressRule(network.MustParsePortRange("80-100/tcp"), "10.0.0.0/24"),
   261  		corefirewall.NewIngressRule(network.MustParsePortRange("443/tcp"), "10.0.0.0/24"),
   262  		corefirewall.NewIngressRule(network.MustParsePortRange("67/udp"), "172.0.0.0/24"),
   263  	}
   264  	err := s.Conn.OpenPortsWithNamer("spam", google.HashSuffixNamer, rules)
   265  	c.Assert(err, jc.ErrorIsNil)
   266  
   267  	c.Check(s.FakeConn.Calls, gc.HasLen, 4)
   268  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   269  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "UpdateFirewall")
   270  	sort.Strings(s.FakeConn.Calls[1].Firewall.Allowed[0].Ports)
   271  	c.Check(s.FakeConn.Calls[1].Name, gc.Equals, "spam-8e65efabcd")
   272  	c.Check(s.FakeConn.Calls[1].Firewall, jc.DeepEquals, &compute.Firewall{
   273  		Name:         "spam-8e65efabcd",
   274  		TargetTags:   []string{"spam"},
   275  		SourceRanges: []string{"172.0.0.0/24"},
   276  		Allowed: []*compute.FirewallAllowed{{
   277  			IPProtocol: "tcp",
   278  			Ports:      []string{"100-120", "443"},
   279  		}, {
   280  			IPProtocol: "udp",
   281  			Ports:      []string{"67"},
   282  		}},
   283  	})
   284  	c.Check(s.FakeConn.Calls[2].FuncName, gc.Equals, "AddFirewall")
   285  	sort.Strings(s.FakeConn.Calls[2].Firewall.Allowed[0].Ports)
   286  	c.Check(s.FakeConn.Calls[2].Firewall, jc.DeepEquals, &compute.Firewall{
   287  		Name:         "spam-a34d80f7b6",
   288  		TargetTags:   []string{"spam"},
   289  		SourceRanges: []string{"10.0.0.0/24"},
   290  		Allowed: []*compute.FirewallAllowed{{
   291  			IPProtocol: "tcp",
   292  			Ports:      []string{"443", "80-100"},
   293  		}},
   294  	})
   295  	c.Check(s.FakeConn.Calls[3].FuncName, gc.Equals, "UpdateFirewall")
   296  	sort.Strings(s.FakeConn.Calls[3].Firewall.Allowed[0].Ports)
   297  	c.Check(s.FakeConn.Calls[3].Name, gc.Equals, "spam-d01a82")
   298  	c.Check(s.FakeConn.Calls[3].Firewall, jc.DeepEquals, &compute.Firewall{
   299  		Name:         "spam-d01a82",
   300  		TargetTags:   []string{"spam"},
   301  		SourceRanges: []string{"192.168.1.0/24"},
   302  		Allowed: []*compute.FirewallAllowed{{
   303  			IPProtocol: "tcp",
   304  			Ports:      []string{"443", "80-81"},
   305  		}},
   306  	})
   307  }
   308  
   309  func (s *connSuite) TestConnectionClosePortsRemove(c *gc.C) {
   310  	s.FakeConn.Firewalls = []*compute.Firewall{{
   311  		Name:         "spam",
   312  		TargetTags:   []string{"spam"},
   313  		SourceRanges: []string{"0.0.0.0/0"},
   314  		Allowed: []*compute.FirewallAllowed{{
   315  			IPProtocol: "tcp",
   316  			Ports:      []string{"443"},
   317  		}},
   318  	}}
   319  
   320  	rules := corefirewall.IngressRules{
   321  		corefirewall.NewIngressRule(network.MustParsePortRange("443/tcp")),
   322  	}
   323  	err := s.Conn.ClosePorts("spam", rules)
   324  	c.Assert(err, jc.ErrorIsNil)
   325  
   326  	c.Check(s.FakeConn.Calls, gc.HasLen, 2)
   327  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   328  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "RemoveFirewall")
   329  	c.Check(s.FakeConn.Calls[1].Name, gc.Equals, "spam")
   330  }
   331  
   332  func (s *connSuite) TestConnectionClosePortsUpdate(c *gc.C) {
   333  	s.FakeConn.Firewalls = []*compute.Firewall{{
   334  		Name:         "spam",
   335  		TargetTags:   []string{"spam"},
   336  		SourceRanges: []string{"0.0.0.0/0"},
   337  		Allowed: []*compute.FirewallAllowed{{
   338  			IPProtocol: "tcp",
   339  			Ports:      []string{"80-81", "443"},
   340  		}},
   341  	}}
   342  
   343  	rules := corefirewall.IngressRules{
   344  		corefirewall.NewIngressRule(network.MustParsePortRange("443/tcp")),
   345  	}
   346  	err := s.Conn.ClosePorts("spam", rules)
   347  	c.Assert(err, jc.ErrorIsNil)
   348  
   349  	c.Check(s.FakeConn.Calls, gc.HasLen, 2)
   350  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   351  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "UpdateFirewall")
   352  	sort.Strings(s.FakeConn.Calls[1].Firewall.Allowed[0].Ports)
   353  	c.Check(s.FakeConn.Calls[1].Firewall, jc.DeepEquals, &compute.Firewall{
   354  		Name:         "spam",
   355  		TargetTags:   []string{"spam"},
   356  		SourceRanges: []string{"0.0.0.0/0"},
   357  		Allowed: []*compute.FirewallAllowed{{
   358  			IPProtocol: "tcp",
   359  			Ports:      []string{"80-81"},
   360  		}},
   361  	})
   362  }
   363  
   364  func (s *connSuite) TestConnectionClosePortsCollapseUpdate(c *gc.C) {
   365  	s.FakeConn.Firewalls = []*compute.Firewall{{
   366  		Name:         "spam",
   367  		TargetTags:   []string{"spam"},
   368  		SourceRanges: []string{"0.0.0.0/0"},
   369  		Allowed: []*compute.FirewallAllowed{{
   370  			IPProtocol: "tcp",
   371  			Ports:      []string{"80-80", "100-120", "81-81", "82-82"},
   372  		}},
   373  	}}
   374  
   375  	rules := corefirewall.IngressRules{
   376  		corefirewall.NewIngressRule(network.MustParsePortRange("80-82/tcp")),
   377  	}
   378  	err := s.Conn.ClosePorts("spam", rules)
   379  	c.Assert(err, jc.ErrorIsNil)
   380  
   381  	c.Check(s.FakeConn.Calls, gc.HasLen, 2)
   382  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   383  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "UpdateFirewall")
   384  	sort.Strings(s.FakeConn.Calls[1].Firewall.Allowed[0].Ports)
   385  	c.Check(s.FakeConn.Calls[1].Firewall, jc.DeepEquals, &compute.Firewall{
   386  		Name:         "spam",
   387  		TargetTags:   []string{"spam"},
   388  		SourceRanges: []string{"0.0.0.0/0"},
   389  		Allowed: []*compute.FirewallAllowed{{
   390  			IPProtocol: "tcp",
   391  			Ports:      []string{"100-120"},
   392  		}},
   393  	})
   394  }
   395  
   396  func (s *connSuite) TestConnectionClosePortsRemoveCIDR(c *gc.C) {
   397  	s.FakeConn.Firewalls = []*compute.Firewall{{
   398  		Name:         "glass-onion",
   399  		TargetTags:   []string{"spam"},
   400  		SourceRanges: []string{"192.168.1.0/24", "10.0.0.0/24"},
   401  		Allowed: []*compute.FirewallAllowed{{
   402  			IPProtocol: "tcp",
   403  			Ports:      []string{"80-81", "443"},
   404  		}},
   405  	}}
   406  
   407  	rules := corefirewall.IngressRules{
   408  		corefirewall.NewIngressRule(network.MustParsePortRange("443/tcp"), "192.168.1.0/24"),
   409  		corefirewall.NewIngressRule(network.MustParsePortRange("80-81/tcp"), "192.168.1.0/24"),
   410  	}
   411  	err := s.Conn.ClosePorts("spam", rules)
   412  	c.Assert(err, jc.ErrorIsNil)
   413  
   414  	c.Check(s.FakeConn.Calls, gc.HasLen, 2)
   415  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   416  	c.Check(s.FakeConn.Calls[1].FuncName, gc.Equals, "UpdateFirewall")
   417  	sort.Strings(s.FakeConn.Calls[1].Firewall.Allowed[0].Ports)
   418  	c.Check(s.FakeConn.Calls[1].Firewall, jc.DeepEquals, &compute.Firewall{
   419  		Name:         "glass-onion",
   420  		TargetTags:   []string{"spam"},
   421  		SourceRanges: []string{"10.0.0.0/24"},
   422  		Allowed: []*compute.FirewallAllowed{{
   423  			IPProtocol: "tcp",
   424  			Ports:      []string{"443", "80-81"},
   425  		}},
   426  	})
   427  }
   428  
   429  func (s *connSuite) TestConnectionCloseMoMatches(c *gc.C) {
   430  	s.FakeConn.Firewalls = []*compute.Firewall{{
   431  		Name:         "spam",
   432  		TargetTags:   []string{"spam"},
   433  		SourceRanges: []string{"0.0.0.0/0"},
   434  		Allowed: []*compute.FirewallAllowed{{
   435  			IPProtocol: "tcp",
   436  			Ports:      []string{"80-81", "443"},
   437  		}},
   438  	}}
   439  
   440  	rules := corefirewall.IngressRules{
   441  		corefirewall.NewIngressRule(network.MustParsePortRange("100-110/tcp"), "192.168.0.1/24"),
   442  	}
   443  	err := s.Conn.ClosePorts("spam", rules)
   444  	c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`closing port(s) [100-110/tcp from 192.168.0.1/24] over non-matching rules not supported`))
   445  
   446  	c.Check(s.FakeConn.Calls, gc.HasLen, 1)
   447  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "GetFirewalls")
   448  }
   449  
   450  func (s *connSuite) TestNetworks(c *gc.C) {
   451  	s.FakeConn.Networks = []*compute.Network{{
   452  		Name: "kamar-taj",
   453  	}}
   454  	results, err := s.Conn.Networks()
   455  	c.Assert(err, jc.ErrorIsNil)
   456  	c.Assert(results, gc.HasLen, 1)
   457  	c.Assert((*results[0]).Name, gc.Equals, "kamar-taj")
   458  
   459  	c.Check(s.FakeConn.Calls, gc.HasLen, 1)
   460  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "ListNetworks")
   461  	c.Check(s.FakeConn.Calls[0].ProjectID, gc.Equals, "spam")
   462  }
   463  
   464  func (s *connSuite) TestSubnetworks(c *gc.C) {
   465  	s.FakeConn.Subnetworks = []*compute.Subnetwork{{
   466  		Name: "heptapod",
   467  	}}
   468  	results, err := s.Conn.Subnetworks("us-central1")
   469  	c.Assert(err, jc.ErrorIsNil)
   470  	c.Assert(results, gc.HasLen, 1)
   471  	c.Assert((*results[0]).Name, gc.Equals, "heptapod")
   472  
   473  	c.Check(s.FakeConn.Calls, gc.HasLen, 1)
   474  	c.Check(s.FakeConn.Calls[0].FuncName, gc.Equals, "ListSubnetworks")
   475  	c.Check(s.FakeConn.Calls[0].ProjectID, gc.Equals, "spam")
   476  	c.Check(s.FakeConn.Calls[0].Region, gc.Equals, "us-central1")
   477  }
   478  
   479  func (s *connSuite) TestRandomSuffixNamer(c *gc.C) {
   480  	ruleset := google.NewRuleSetFromRules(corefirewall.IngressRules{
   481  		corefirewall.NewIngressRule(network.MustParsePortRange("80-90/tcp")),
   482  		corefirewall.NewIngressRule(network.MustParsePortRange("80-90/tcp"), "10.0.10.0/24"),
   483  	})
   484  	i := 0
   485  	for _, firewall := range ruleset {
   486  		i++
   487  		c.Logf("%#v", *firewall)
   488  		name, err := google.RandomSuffixNamer(firewall, "mischief", set.NewStrings())
   489  		c.Assert(err, jc.ErrorIsNil)
   490  		if firewall.SourceCIDRs[0] == "0.0.0.0/0" {
   491  			c.Assert(name, gc.Equals, "mischief")
   492  		} else {
   493  			c.Assert(name, gc.Matches, "mischief-[0-9a-f]{8}")
   494  		}
   495  	}
   496  	c.Assert(i, gc.Equals, 2)
   497  }