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 }