github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/gce/google/ruleset_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package google
     5  
     6  import (
     7  	"github.com/juju/collections/set"
     8  	jc "github.com/juju/testing/checkers"
     9  	"google.golang.org/api/compute/v1"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	corenetwork "github.com/juju/juju/core/network"
    13  	"github.com/juju/juju/network"
    14  	"github.com/juju/juju/testing"
    15  )
    16  
    17  type RuleSetSuite struct {
    18  	testing.BaseSuite
    19  }
    20  
    21  var _ = gc.Suite(&RuleSetSuite{})
    22  
    23  func makeRuleSet() ruleSet {
    24  	rule1 := network.MustNewIngressRule("tcp", 8000, 8099)
    25  	rule2 := network.MustNewIngressRule("tcp", 80, 80)
    26  	rule3 := network.MustNewIngressRule("tcp", 79, 81)
    27  	rule4 := network.MustNewIngressRule("udp", 5123, 8099, "192.168.1.0/24")
    28  	return newRuleSetFromRules(rule1, rule2, rule3, rule4)
    29  }
    30  
    31  func (s *RuleSetSuite) TestNewRuleSetFromRules(c *gc.C) {
    32  	rs := makeRuleSet()
    33  	c.Assert(rs, jc.DeepEquals, ruleSet{
    34  		"b42e18366a": &firewall{
    35  			SourceCIDRs: []string{"0.0.0.0/0"},
    36  			AllowedPorts: protocolPorts{
    37  				"tcp": []corenetwork.PortRange{{8000, 8099, "tcp"}, {80, 80, "tcp"}, {79, 81, "tcp"}},
    38  			},
    39  		},
    40  		"d01a825c13": &firewall{
    41  			SourceCIDRs: []string{"192.168.1.0/24"},
    42  			AllowedPorts: protocolPorts{
    43  				"udp": []corenetwork.PortRange{{5123, 8099, "udp"}},
    44  			},
    45  		},
    46  	})
    47  }
    48  
    49  func newFirewall(name, target string, sourceRanges []string, ports map[string][]string) *compute.Firewall {
    50  	allowed := make([]*compute.FirewallAllowed, len(ports))
    51  	i := 0
    52  	for protocol, ranges := range ports {
    53  		allowed[i] = &compute.FirewallAllowed{
    54  			IPProtocol: protocol,
    55  			Ports:      ranges,
    56  		}
    57  		i++
    58  	}
    59  	return &compute.Firewall{
    60  		Name:         name,
    61  		TargetTags:   []string{target},
    62  		SourceRanges: sourceRanges,
    63  		Allowed:      allowed,
    64  	}
    65  }
    66  
    67  func (s *RuleSetSuite) TestNewRuleSetFromFirewalls(c *gc.C) {
    68  	ports := map[string][]string{
    69  		"tcp": {"80", "443", "17070-17073"},
    70  		"udp": {"123"},
    71  	}
    72  	fw1 := newFirewall("weeps", "target", []string{"1.2.3.0/24", "2.3.4.0/24"}, ports)
    73  	fw2 := newFirewall("blackbird", "somewhere", nil, ports)
    74  	ruleset, err := newRuleSetFromFirewalls(fw1, fw2)
    75  	c.Assert(err, jc.ErrorIsNil)
    76  	c.Assert(ruleset, gc.DeepEquals, ruleSet{
    77  		"b42e18366a": &firewall{
    78  			Name:        "blackbird",
    79  			Target:      "somewhere",
    80  			SourceCIDRs: []string{"0.0.0.0/0"},
    81  			AllowedPorts: protocolPorts{
    82  				"tcp": []corenetwork.PortRange{{80, 80, "tcp"}, {443, 443, "tcp"}, {17070, 17073, "tcp"}},
    83  				"udp": []corenetwork.PortRange{{123, 123, "udp"}},
    84  			},
    85  		},
    86  		"0e3c16a771": &firewall{
    87  			Name:        "weeps",
    88  			Target:      "target",
    89  			SourceCIDRs: []string{"1.2.3.0/24", "2.3.4.0/24"},
    90  			AllowedPorts: protocolPorts{
    91  				"tcp": []corenetwork.PortRange{{80, 80, "tcp"}, {443, 443, "tcp"}, {17070, 17073, "tcp"}},
    92  				"udp": []corenetwork.PortRange{{123, 123, "udp"}},
    93  			},
    94  		},
    95  	})
    96  }
    97  
    98  func (s *RuleSetSuite) TestProtocolPortsUnion(c *gc.C) {
    99  	p1 := protocolPorts{"tcp": []corenetwork.PortRange{{8000, 8099, "tcp"}, {80, 80, "tcp"}, {79, 81, "tcp"}}}
   100  	p2 := protocolPorts{
   101  		"tcp": []corenetwork.PortRange{{80, 80, "tcp"}, {80, 100, "tcp"}, {443, 443, "tcp"}},
   102  		"udp": []corenetwork.PortRange{{67, 67, "udp"}},
   103  	}
   104  	result := p1.union(p2)
   105  	c.Assert(result, jc.DeepEquals, protocolPorts{
   106  		"tcp": []corenetwork.PortRange{{8000, 8099, "tcp"}, {80, 80, "tcp"}, {79, 81, "tcp"}, {80, 100, "tcp"}, {443, 443, "tcp"}},
   107  		"udp": []corenetwork.PortRange{{67, 67, "udp"}},
   108  	})
   109  }
   110  
   111  func (s *RuleSetSuite) TestProtocolPortsRemove(c *gc.C) {
   112  	p1 := protocolPorts{"tcp": []corenetwork.PortRange{{8000, 8099, "tcp"}, {80, 80, "tcp"}, {79, 81, "tcp"}}}
   113  	p2 := protocolPorts{
   114  		"tcp": []corenetwork.PortRange{{80, 100, "tcp"}, {443, 443, "tcp"}, {80, 80, "tcp"}},
   115  	}
   116  	result := p1.remove(p2)
   117  	c.Assert(result, jc.DeepEquals, protocolPorts{
   118  		"tcp": []corenetwork.PortRange{{8000, 8099, "tcp"}, {79, 81, "tcp"}},
   119  	})
   120  }
   121  
   122  func (s *RuleSetSuite) TestRuleSetToIngressRules(c *gc.C) {
   123  	ports := map[string][]string{
   124  		"tcp": {"80", "443", "17070-17073"},
   125  		"udp": {"123"},
   126  	}
   127  	fw1 := newFirewall("weeps", "target", []string{"1.2.3.0/24", "2.3.4.0/24"}, ports)
   128  	fw2 := newFirewall("blackbird", "somewhere", nil, ports)
   129  	ruleset, err := newRuleSetFromFirewalls(fw1, fw2)
   130  	c.Assert(err, jc.ErrorIsNil)
   131  	rules, err := ruleset.toIngressRules()
   132  	c.Assert(err, jc.ErrorIsNil)
   133  	c.Assert(rules, gc.DeepEquals, []network.IngressRule{
   134  		network.MustNewIngressRule("tcp", 80, 80, "0.0.0.0/0"),
   135  		network.MustNewIngressRule("tcp", 80, 80, "1.2.3.0/24", "2.3.4.0/24"),
   136  		network.MustNewIngressRule("tcp", 443, 443, "0.0.0.0/0"),
   137  		network.MustNewIngressRule("tcp", 443, 443, "1.2.3.0/24", "2.3.4.0/24"),
   138  		network.MustNewIngressRule("tcp", 17070, 17073, "0.0.0.0/0"),
   139  		network.MustNewIngressRule("tcp", 17070, 17073, "1.2.3.0/24", "2.3.4.0/24"),
   140  		network.MustNewIngressRule("udp", 123, 123, "0.0.0.0/0"),
   141  		network.MustNewIngressRule("udp", 123, 123, "1.2.3.0/24", "2.3.4.0/24"),
   142  	})
   143  }
   144  
   145  func (s *RuleSetSuite) TestMatchPorts(c *gc.C) {
   146  	ruleset := makeRuleSet()
   147  	fw, ok := ruleset.matchProtocolPorts(protocolPorts{
   148  		"udp": {{5123, 8099, "udp"}},
   149  	})
   150  	c.Assert(ok, jc.IsTrue)
   151  	c.Assert(fw, gc.DeepEquals, &firewall{
   152  		AllowedPorts: protocolPorts{
   153  			"udp": {{5123, 8099, "udp"}},
   154  		},
   155  		SourceCIDRs: []string{"192.168.1.0/24"},
   156  	})
   157  	// No partial matches.
   158  	fw, ok = ruleset.matchProtocolPorts(protocolPorts{
   159  		"tcp": {{80, 80, "tcp"}},
   160  	})
   161  	c.Assert(ok, jc.IsFalse)
   162  	c.Assert(fw, gc.IsNil)
   163  }
   164  
   165  func (s *RuleSetSuite) TestMatchSourceCIDRs(c *gc.C) {
   166  	ruleset := makeRuleSet()
   167  	c.Logf("%#v", ruleset)
   168  	c.Logf("%s", sourcecidrs([]string{"0.0.0.0/0"}).key())
   169  	fw, ok := ruleset.matchSourceCIDRs([]string{"0.0.0.0/0"})
   170  	c.Assert(ok, jc.IsTrue)
   171  	c.Assert(fw, gc.DeepEquals, &firewall{
   172  		SourceCIDRs: []string{"0.0.0.0/0"},
   173  		AllowedPorts: protocolPorts{
   174  			"tcp": []corenetwork.PortRange{{8000, 8099, "tcp"}, {80, 80, "tcp"}, {79, 81, "tcp"}},
   175  		},
   176  	})
   177  	fw, ok = ruleset.matchSourceCIDRs([]string{"1.2.3.0/24"})
   178  	c.Assert(ok, jc.IsFalse)
   179  	c.Assert(fw, gc.IsNil)
   180  }
   181  
   182  func (s *RuleSetSuite) TestAllNames(c *gc.C) {
   183  	ports := map[string][]string{"tcp": {"80"}}
   184  	fw1 := newFirewall("weeps", "target", []string{"1.2.3.0/24", "2.3.4.0/24"}, ports)
   185  	fw2 := newFirewall("blackbird", "somewhere", nil, ports)
   186  	ruleset, err := newRuleSetFromFirewalls(fw1, fw2)
   187  	c.Assert(err, jc.ErrorIsNil)
   188  	c.Assert(ruleset.allNames(), gc.DeepEquals, set.NewStrings("weeps", "blackbird"))
   189  }
   190  
   191  func (s *RuleSetSuite) TestDifferentOrdersForCIDRs(c *gc.C) {
   192  	rule1 := network.MustNewIngressRule("tcp", 8000, 8099, "1.2.3.0/24", "4.3.2.0/24")
   193  	rule2 := network.MustNewIngressRule("tcp", 80, 80, "4.3.2.0/24", "1.2.3.0/24")
   194  	ruleset := NewRuleSetFromRules(rule1, rule2)
   195  	// They should be combined into one firewall rule.
   196  	c.Assert(ruleset, gc.HasLen, 1)
   197  	for _, fw := range ruleset {
   198  		c.Assert(fw, gc.DeepEquals, &firewall{
   199  			SourceCIDRs: []string{"1.2.3.0/24", "4.3.2.0/24"},
   200  			AllowedPorts: protocolPorts{
   201  				"tcp": []corenetwork.PortRange{{8000, 8099, "tcp"}, {80, 80, "tcp"}},
   202  			},
   203  		})
   204  	}
   205  }