github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/controller/firewaller/firewaller_test.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package firewaller_test 5 6 import ( 7 "sort" 8 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/common/cloudspec" 15 commontesting "github.com/juju/juju/apiserver/common/testing" 16 "github.com/juju/juju/apiserver/facade" 17 "github.com/juju/juju/apiserver/facades/controller/firewaller" 18 "github.com/juju/juju/apiserver/params" 19 apiservertesting "github.com/juju/juju/apiserver/testing" 20 "github.com/juju/juju/state" 21 statetesting "github.com/juju/juju/state/testing" 22 coretesting "github.com/juju/juju/testing" 23 ) 24 25 type firewallerSuite struct { 26 firewallerBaseSuite 27 *commontesting.ModelWatcherTest 28 29 firewaller *firewaller.FirewallerAPIV3 30 } 31 32 var _ = gc.Suite(&firewallerSuite{}) 33 34 func (s *firewallerSuite) SetUpTest(c *gc.C) { 35 s.firewallerBaseSuite.setUpTest(c) 36 37 _, err := s.State.AddSubnet(state.SubnetInfo{CIDR: "10.20.30.0/24"}) 38 c.Assert(err, jc.ErrorIsNil) 39 40 cloudSpecAPI := cloudspec.NewCloudSpec( 41 cloudspec.MakeCloudSpecGetterForModel(s.State), 42 common.AuthFuncForTag(s.Model.ModelTag()), 43 ) 44 // Create a firewaller API for the machine. 45 firewallerAPI, err := firewaller.NewFirewallerAPI( 46 firewaller.StateShim(s.State, s.Model), 47 s.resources, 48 s.authorizer, 49 cloudSpecAPI, 50 ) 51 c.Assert(err, jc.ErrorIsNil) 52 s.firewaller = firewallerAPI 53 s.ModelWatcherTest = commontesting.NewModelWatcherTest(s.firewaller, s.State, s.resources) 54 } 55 56 func (s *firewallerSuite) TestFirewallerFailsWithNonControllerUser(c *gc.C) { 57 constructor := func(st *state.State, res facade.Resources, auth facade.Authorizer) error { 58 m, err := st.Model() 59 c.Assert(err, jc.ErrorIsNil) 60 61 _, err = firewaller.NewFirewallerAPI(firewaller.StateShim(st, m), res, auth, nil) 62 return err 63 } 64 s.testFirewallerFailsWithNonControllerUser(c, constructor) 65 } 66 67 func (s *firewallerSuite) TestLife(c *gc.C) { 68 s.testLife(c, s.firewaller) 69 } 70 71 func (s *firewallerSuite) TestInstanceId(c *gc.C) { 72 s.testInstanceId(c, s.firewaller) 73 } 74 75 func (s *firewallerSuite) TestWatchModelMachines(c *gc.C) { 76 s.testWatchModelMachines(c, s.firewaller) 77 } 78 79 func (s *firewallerSuite) TestWatch(c *gc.C) { 80 s.testWatch(c, s.firewaller, cannotWatchUnits) 81 } 82 83 func (s *firewallerSuite) TestWatchUnits(c *gc.C) { 84 s.testWatchUnits(c, s.firewaller) 85 } 86 87 func (s *firewallerSuite) TestGetExposed(c *gc.C) { 88 s.testGetExposed(c, s.firewaller) 89 } 90 91 func (s *firewallerSuite) TestGetAssignedMachine(c *gc.C) { 92 s.testGetAssignedMachine(c, s.firewaller) 93 } 94 95 func (s *firewallerSuite) openPorts(c *gc.C) { 96 // Open some ports on the units. 97 err := s.units[0].OpenPortsOnSubnet("10.20.30.0/24", "tcp", 1234, 1400) 98 c.Assert(err, jc.ErrorIsNil) 99 err = s.units[0].OpenPort("tcp", 4321) 100 c.Assert(err, jc.ErrorIsNil) 101 err = s.units[2].OpenPorts("udp", 1111, 2222) 102 c.Assert(err, jc.ErrorIsNil) 103 } 104 105 func (s *firewallerSuite) TestWatchOpenedPorts(c *gc.C) { 106 c.Assert(s.resources.Count(), gc.Equals, 0) 107 108 s.openPorts(c) 109 expectChanges := []string{ 110 "0:", // empty subnet is ok (until it can be made mandatory) 111 "0:10.20.30.0/24", 112 "2:", 113 } 114 115 fakeModelTag := names.NewModelTag("deadbeef-deaf-face-feed-0123456789ab") 116 args := addFakeEntities(params.Entities{Entities: []params.Entity{ 117 {Tag: fakeModelTag.String()}, 118 {Tag: s.machines[0].Tag().String()}, 119 {Tag: s.application.Tag().String()}, 120 {Tag: s.units[0].Tag().String()}, 121 }}) 122 result, err := s.firewaller.WatchOpenedPorts(args) 123 sort.Strings(result.Results[0].Changes) 124 c.Assert(err, jc.ErrorIsNil) 125 c.Assert(result, jc.DeepEquals, params.StringsWatchResults{ 126 Results: []params.StringsWatchResult{ 127 {Changes: expectChanges, StringsWatcherId: "1"}, 128 {Error: apiservertesting.ErrUnauthorized}, 129 {Error: apiservertesting.ErrUnauthorized}, 130 {Error: apiservertesting.ErrUnauthorized}, 131 {Error: apiservertesting.ErrUnauthorized}, 132 {Error: apiservertesting.ErrUnauthorized}, 133 {Error: apiservertesting.ErrUnauthorized}, 134 {Error: apiservertesting.ErrUnauthorized}, 135 {Error: apiservertesting.ErrUnauthorized}, 136 {Error: apiservertesting.ErrUnauthorized}, 137 }, 138 }) 139 140 // Verify the resource was registered and stop when done 141 c.Assert(s.resources.Count(), gc.Equals, 1) 142 c.Assert(result.Results[0].StringsWatcherId, gc.Equals, "1") 143 resource := s.resources.Get("1") 144 defer statetesting.AssertStop(c, resource) 145 146 // Check that the Watch has consumed the initial event ("returned" in 147 // the Watch call) 148 wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher)) 149 wc.AssertNoChange() 150 } 151 152 func (s *firewallerSuite) TestGetMachinePorts(c *gc.C) { 153 s.openPorts(c) 154 155 subnetTag := names.NewSubnetTag("10.20.30.0/24").String() 156 args := params.MachinePortsParams{ 157 Params: []params.MachinePorts{ 158 {MachineTag: s.machines[0].Tag().String(), SubnetTag: ""}, 159 {MachineTag: s.machines[0].Tag().String(), SubnetTag: subnetTag}, 160 {MachineTag: s.machines[1].Tag().String(), SubnetTag: ""}, 161 {MachineTag: s.machines[2].Tag().String(), SubnetTag: ""}, 162 {MachineTag: s.machines[0].Tag().String(), SubnetTag: "invalid"}, 163 {MachineTag: "machine-42", SubnetTag: ""}, 164 {MachineTag: s.machines[0].Tag().String(), SubnetTag: "subnet-bad"}, 165 }, 166 } 167 unit0Tag := s.units[0].Tag().String() 168 expectPortsMachine0NoSubnet := []params.MachinePortRange{ 169 {UnitTag: unit0Tag, PortRange: params.PortRange{ 170 FromPort: 4321, ToPort: 4321, Protocol: "tcp", 171 }}, 172 } 173 expectPortsMachine0WithSubnet := []params.MachinePortRange{ 174 {UnitTag: unit0Tag, PortRange: params.PortRange{ 175 FromPort: 1234, ToPort: 1400, Protocol: "tcp", 176 }}, 177 } 178 unit2Tag := s.units[2].Tag().String() 179 expectPortsMachine2 := []params.MachinePortRange{ 180 {UnitTag: unit2Tag, PortRange: params.PortRange{ 181 FromPort: 1111, ToPort: 2222, Protocol: "udp", 182 }}, 183 } 184 result, err := s.firewaller.GetMachinePorts(args) 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(result, jc.DeepEquals, params.MachinePortsResults{ 187 Results: []params.MachinePortsResult{ 188 {Ports: expectPortsMachine0NoSubnet}, 189 {Ports: expectPortsMachine0WithSubnet}, 190 {Error: nil, Ports: nil}, 191 {Ports: expectPortsMachine2}, 192 {Error: apiservertesting.ServerError(`"invalid" is not a valid tag`)}, 193 {Error: apiservertesting.NotFoundError("machine 42")}, 194 {Error: apiservertesting.ServerError(`"subnet-bad" is not a valid subnet tag`)}, 195 }, 196 }) 197 198 } 199 200 func (s *firewallerSuite) TestGetMachineActiveSubnets(c *gc.C) { 201 s.openPorts(c) 202 203 subnetTag := names.NewSubnetTag("10.20.30.0/24").String() 204 args := addFakeEntities(params.Entities{Entities: []params.Entity{ 205 {Tag: s.machines[0].Tag().String()}, 206 {Tag: s.machines[1].Tag().String()}, 207 {Tag: s.machines[2].Tag().String()}, 208 {Tag: s.application.Tag().String()}, 209 {Tag: s.units[0].Tag().String()}, 210 }}) 211 expectResultsMachine0 := []string{subnetTag, ""} 212 expectResultsMachine2 := []string{""} 213 result, err := s.firewaller.GetMachineActiveSubnets(args) 214 c.Assert(err, jc.ErrorIsNil) 215 c.Assert(result, jc.DeepEquals, params.StringsResults{ 216 Results: []params.StringsResult{ 217 {Result: expectResultsMachine0}, 218 {Result: nil, Error: nil}, 219 {Result: expectResultsMachine2}, 220 {Error: apiservertesting.ServerError(`"application-wordpress" is not a valid machine tag`)}, 221 {Error: apiservertesting.ServerError(`"unit-wordpress-0" is not a valid machine tag`)}, 222 {Error: apiservertesting.NotFoundError("machine 42")}, 223 {Error: apiservertesting.ServerError(`"unit-foo-0" is not a valid machine tag`)}, 224 {Error: apiservertesting.ServerError(`"application-bar" is not a valid machine tag`)}, 225 {Error: apiservertesting.ServerError(`"user-foo" is not a valid machine tag`)}, 226 {Error: apiservertesting.ServerError(`"foo-bar" is not a valid tag`)}, 227 {Error: apiservertesting.ServerError(`"" is not a valid tag`)}, 228 }, 229 }) 230 } 231 232 func (s *firewallerSuite) TestAreManuallyProvisioned(c *gc.C) { 233 m, err := s.State.AddOneMachine(state.MachineTemplate{ 234 Series: "quantal", 235 Jobs: []state.MachineJob{state.JobHostUnits}, 236 InstanceId: "2", 237 Nonce: "manual:", 238 }) 239 c.Assert(err, jc.ErrorIsNil) 240 241 args := addFakeEntities(params.Entities{Entities: []params.Entity{ 242 {Tag: s.machines[0].Tag().String()}, 243 {Tag: s.machines[1].Tag().String()}, 244 {Tag: m.Tag().String()}, 245 {Tag: s.application.Tag().String()}, 246 {Tag: s.units[0].Tag().String()}, 247 }}) 248 249 apiv5 := &firewaller.FirewallerAPIV5{ 250 &firewaller.FirewallerAPIV4{ 251 FirewallerAPIV3: s.firewaller, 252 ControllerConfigAPI: common.NewControllerConfig(newMockState(coretesting.ModelTag.Id())), 253 }} 254 255 result, err := apiv5.AreManuallyProvisioned(args) 256 c.Assert(err, jc.ErrorIsNil) 257 c.Assert(result, jc.DeepEquals, params.BoolResults{ 258 Results: []params.BoolResult{ 259 {Result: false, Error: nil}, 260 {Result: false, Error: nil}, 261 {Result: true, Error: nil}, 262 {Result: false, Error: apiservertesting.ServerError(`"application-wordpress" is not a valid machine tag`)}, 263 {Result: false, Error: apiservertesting.ServerError(`"unit-wordpress-0" is not a valid machine tag`)}, 264 {Result: false, Error: apiservertesting.NotFoundError("machine 42")}, 265 {Result: false, Error: apiservertesting.ServerError(`"unit-foo-0" is not a valid machine tag`)}, 266 {Result: false, Error: apiservertesting.ServerError(`"application-bar" is not a valid machine tag`)}, 267 {Result: false, Error: apiservertesting.ServerError(`"user-foo" is not a valid machine tag`)}, 268 {Result: false, Error: apiservertesting.ServerError(`"foo-bar" is not a valid tag`)}, 269 {Result: false, Error: apiservertesting.ServerError(`"" is not a valid tag`)}, 270 }, 271 }) 272 }