github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/worker/firewaller/firewaller_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package firewaller_test 5 6 import ( 7 "reflect" 8 "time" 9 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/utils" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/api" 15 apifirewaller "github.com/juju/juju/api/firewaller" 16 "github.com/juju/juju/environs/config" 17 "github.com/juju/juju/instance" 18 "github.com/juju/juju/juju" 19 "github.com/juju/juju/juju/testing" 20 "github.com/juju/juju/network" 21 "github.com/juju/juju/provider/dummy" 22 "github.com/juju/juju/state" 23 statetesting "github.com/juju/juju/state/testing" 24 coretesting "github.com/juju/juju/testing" 25 "github.com/juju/juju/worker" 26 "github.com/juju/juju/worker/firewaller" 27 "github.com/juju/juju/worker/workertest" 28 ) 29 30 // firewallerBaseSuite implements common functionality for embedding 31 // into each of the other per-mode suites. 32 type firewallerBaseSuite struct { 33 testing.JujuConnSuite 34 op <-chan dummy.Operation 35 charm *state.Charm 36 37 st api.Connection 38 firewaller *apifirewaller.State 39 } 40 41 var _ worker.Worker = (*firewaller.Firewaller)(nil) 42 43 func (s *firewallerBaseSuite) setUpTest(c *gc.C, firewallMode string) { 44 add := map[string]interface{}{"firewall-mode": firewallMode} 45 s.DummyConfig = dummy.SampleConfig().Merge(add).Delete("admin-secret") 46 47 s.JujuConnSuite.SetUpTest(c) 48 s.charm = s.AddTestingCharm(c, "dummy") 49 50 // Create a manager machine and login to the API. 51 machine, err := s.State.AddMachine("quantal", state.JobManageModel) 52 c.Assert(err, jc.ErrorIsNil) 53 password, err := utils.RandomPassword() 54 c.Assert(err, jc.ErrorIsNil) 55 err = machine.SetPassword(password) 56 c.Assert(err, jc.ErrorIsNil) 57 err = machine.SetProvisioned("i-manager", "fake_nonce", nil) 58 c.Assert(err, jc.ErrorIsNil) 59 s.st = s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce") 60 c.Assert(s.st, gc.NotNil) 61 62 // Create the firewaller API facade. 63 s.firewaller = apifirewaller.NewState(s.st) 64 c.Assert(s.firewaller, gc.NotNil) 65 } 66 67 // assertPorts retrieves the open ports of the instance and compares them 68 // to the expected. 69 func (s *firewallerBaseSuite) assertPorts(c *gc.C, inst instance.Instance, machineId string, expected []network.PortRange) { 70 s.BackingState.StartSync() 71 start := time.Now() 72 for { 73 got, err := inst.Ports(machineId) 74 if err != nil { 75 c.Fatal(err) 76 return 77 } 78 network.SortPortRanges(got) 79 network.SortPortRanges(expected) 80 if reflect.DeepEqual(got, expected) { 81 c.Succeed() 82 return 83 } 84 if time.Since(start) > coretesting.LongWait { 85 c.Fatalf("timed out: expected %q; got %q", expected, got) 86 return 87 } 88 time.Sleep(coretesting.ShortWait) 89 } 90 } 91 92 // assertEnvironPorts retrieves the open ports of environment and compares them 93 // to the expected. 94 func (s *firewallerBaseSuite) assertEnvironPorts(c *gc.C, expected []network.PortRange) { 95 s.BackingState.StartSync() 96 start := time.Now() 97 for { 98 got, err := s.Environ.Ports() 99 if err != nil { 100 c.Fatal(err) 101 return 102 } 103 network.SortPortRanges(got) 104 network.SortPortRanges(expected) 105 if reflect.DeepEqual(got, expected) { 106 c.Succeed() 107 return 108 } 109 if time.Since(start) > coretesting.LongWait { 110 c.Fatalf("timed out: expected %q; got %q", expected, got) 111 return 112 } 113 time.Sleep(coretesting.ShortWait) 114 } 115 } 116 117 func (s *firewallerBaseSuite) addUnit(c *gc.C, app *state.Application) (*state.Unit, *state.Machine) { 118 units, err := juju.AddUnits(s.State, app, app.Name(), 1, nil) 119 c.Assert(err, jc.ErrorIsNil) 120 u := units[0] 121 id, err := u.AssignedMachineId() 122 c.Assert(err, jc.ErrorIsNil) 123 m, err := s.State.Machine(id) 124 c.Assert(err, jc.ErrorIsNil) 125 return u, m 126 } 127 128 // startInstance starts a new instance for the given machine. 129 func (s *firewallerBaseSuite) startInstance(c *gc.C, m *state.Machine) instance.Instance { 130 inst, hc := testing.AssertStartInstance(c, s.Environ, s.ControllerConfig.ControllerUUID(), m.Id()) 131 err := m.SetProvisioned(inst.Id(), "fake_nonce", hc) 132 c.Assert(err, jc.ErrorIsNil) 133 return inst 134 } 135 136 type InstanceModeSuite struct { 137 firewallerBaseSuite 138 } 139 140 var _ = gc.Suite(&InstanceModeSuite{}) 141 142 func (s *InstanceModeSuite) SetUpTest(c *gc.C) { 143 s.firewallerBaseSuite.setUpTest(c, config.FwInstance) 144 } 145 146 func (s *InstanceModeSuite) TearDownTest(c *gc.C) { 147 s.firewallerBaseSuite.JujuConnSuite.TearDownTest(c) 148 } 149 150 func (s *InstanceModeSuite) TestStartStop(c *gc.C) { 151 fw, err := firewaller.NewFirewaller(s.firewaller) 152 c.Assert(err, jc.ErrorIsNil) 153 statetesting.AssertKillAndWait(c, fw) 154 } 155 156 func (s *InstanceModeSuite) TestNotExposedService(c *gc.C) { 157 fw, err := firewaller.NewFirewaller(s.firewaller) 158 c.Assert(err, jc.ErrorIsNil) 159 defer statetesting.AssertKillAndWait(c, fw) 160 161 app := s.AddTestingService(c, "wordpress", s.charm) 162 u, m := s.addUnit(c, app) 163 inst := s.startInstance(c, m) 164 165 err = u.OpenPort("tcp", 80) 166 c.Assert(err, jc.ErrorIsNil) 167 err = u.OpenPort("tcp", 8080) 168 c.Assert(err, jc.ErrorIsNil) 169 170 s.assertPorts(c, inst, m.Id(), nil) 171 172 err = u.ClosePort("tcp", 80) 173 c.Assert(err, jc.ErrorIsNil) 174 175 s.assertPorts(c, inst, m.Id(), nil) 176 } 177 178 func (s *InstanceModeSuite) TestExposedService(c *gc.C) { 179 fw, err := firewaller.NewFirewaller(s.firewaller) 180 c.Assert(err, jc.ErrorIsNil) 181 defer statetesting.AssertKillAndWait(c, fw) 182 183 app := s.AddTestingService(c, "wordpress", s.charm) 184 185 err = app.SetExposed() 186 c.Assert(err, jc.ErrorIsNil) 187 u, m := s.addUnit(c, app) 188 inst := s.startInstance(c, m) 189 190 err = u.OpenPorts("tcp", 80, 90) 191 c.Assert(err, jc.ErrorIsNil) 192 err = u.OpenPort("tcp", 8080) 193 c.Assert(err, jc.ErrorIsNil) 194 195 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 90, "tcp"}, {8080, 8080, "tcp"}}) 196 197 err = u.ClosePorts("tcp", 80, 90) 198 c.Assert(err, jc.ErrorIsNil) 199 200 s.assertPorts(c, inst, m.Id(), []network.PortRange{{8080, 8080, "tcp"}}) 201 } 202 203 func (s *InstanceModeSuite) TestMultipleExposedServices(c *gc.C) { 204 fw, err := firewaller.NewFirewaller(s.firewaller) 205 c.Assert(err, jc.ErrorIsNil) 206 defer statetesting.AssertKillAndWait(c, fw) 207 208 app1 := s.AddTestingService(c, "wordpress", s.charm) 209 err = app1.SetExposed() 210 c.Assert(err, jc.ErrorIsNil) 211 212 u1, m1 := s.addUnit(c, app1) 213 inst1 := s.startInstance(c, m1) 214 err = u1.OpenPort("tcp", 80) 215 c.Assert(err, jc.ErrorIsNil) 216 err = u1.OpenPort("tcp", 8080) 217 c.Assert(err, jc.ErrorIsNil) 218 219 app2 := s.AddTestingService(c, "mysql", s.charm) 220 c.Assert(err, jc.ErrorIsNil) 221 err = app2.SetExposed() 222 c.Assert(err, jc.ErrorIsNil) 223 224 u2, m2 := s.addUnit(c, app2) 225 inst2 := s.startInstance(c, m2) 226 err = u2.OpenPort("tcp", 3306) 227 c.Assert(err, jc.ErrorIsNil) 228 229 s.assertPorts(c, inst1, m1.Id(), []network.PortRange{{80, 80, "tcp"}, {8080, 8080, "tcp"}}) 230 s.assertPorts(c, inst2, m2.Id(), []network.PortRange{{3306, 3306, "tcp"}}) 231 232 err = u1.ClosePort("tcp", 80) 233 c.Assert(err, jc.ErrorIsNil) 234 err = u2.ClosePort("tcp", 3306) 235 c.Assert(err, jc.ErrorIsNil) 236 237 s.assertPorts(c, inst1, m1.Id(), []network.PortRange{{8080, 8080, "tcp"}}) 238 s.assertPorts(c, inst2, m2.Id(), nil) 239 } 240 241 func (s *InstanceModeSuite) TestMachineWithoutInstanceId(c *gc.C) { 242 fw, err := firewaller.NewFirewaller(s.firewaller) 243 c.Assert(err, jc.ErrorIsNil) 244 defer statetesting.AssertKillAndWait(c, fw) 245 246 app := s.AddTestingService(c, "wordpress", s.charm) 247 err = app.SetExposed() 248 c.Assert(err, jc.ErrorIsNil) 249 // add a unit but don't start its instance yet. 250 u1, m1 := s.addUnit(c, app) 251 252 // add another unit and start its instance, so that 253 // we're sure the firewaller has seen the first instance. 254 u2, m2 := s.addUnit(c, app) 255 inst2 := s.startInstance(c, m2) 256 err = u2.OpenPort("tcp", 80) 257 c.Assert(err, jc.ErrorIsNil) 258 s.assertPorts(c, inst2, m2.Id(), []network.PortRange{{80, 80, "tcp"}}) 259 260 inst1 := s.startInstance(c, m1) 261 err = u1.OpenPort("tcp", 8080) 262 c.Assert(err, jc.ErrorIsNil) 263 s.assertPorts(c, inst1, m1.Id(), []network.PortRange{{8080, 8080, "tcp"}}) 264 } 265 266 func (s *InstanceModeSuite) TestMultipleUnits(c *gc.C) { 267 fw, err := firewaller.NewFirewaller(s.firewaller) 268 c.Assert(err, jc.ErrorIsNil) 269 defer statetesting.AssertKillAndWait(c, fw) 270 271 app := s.AddTestingService(c, "wordpress", s.charm) 272 err = app.SetExposed() 273 c.Assert(err, jc.ErrorIsNil) 274 275 u1, m1 := s.addUnit(c, app) 276 inst1 := s.startInstance(c, m1) 277 err = u1.OpenPort("tcp", 80) 278 c.Assert(err, jc.ErrorIsNil) 279 280 u2, m2 := s.addUnit(c, app) 281 inst2 := s.startInstance(c, m2) 282 err = u2.OpenPort("tcp", 80) 283 c.Assert(err, jc.ErrorIsNil) 284 285 s.assertPorts(c, inst1, m1.Id(), []network.PortRange{{80, 80, "tcp"}}) 286 s.assertPorts(c, inst2, m2.Id(), []network.PortRange{{80, 80, "tcp"}}) 287 288 err = u1.ClosePort("tcp", 80) 289 c.Assert(err, jc.ErrorIsNil) 290 err = u2.ClosePort("tcp", 80) 291 c.Assert(err, jc.ErrorIsNil) 292 293 s.assertPorts(c, inst1, m1.Id(), nil) 294 s.assertPorts(c, inst2, m2.Id(), nil) 295 } 296 297 func (s *InstanceModeSuite) TestStartWithState(c *gc.C) { 298 app := s.AddTestingService(c, "wordpress", s.charm) 299 err := app.SetExposed() 300 c.Assert(err, jc.ErrorIsNil) 301 u, m := s.addUnit(c, app) 302 inst := s.startInstance(c, m) 303 304 err = u.OpenPort("tcp", 80) 305 c.Assert(err, jc.ErrorIsNil) 306 err = u.OpenPort("tcp", 8080) 307 c.Assert(err, jc.ErrorIsNil) 308 309 // Nothing open without firewaller. 310 s.assertPorts(c, inst, m.Id(), nil) 311 312 // Starting the firewaller opens the ports. 313 fw, err := firewaller.NewFirewaller(s.firewaller) 314 c.Assert(err, jc.ErrorIsNil) 315 defer statetesting.AssertKillAndWait(c, fw) 316 317 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 80, "tcp"}, {8080, 8080, "tcp"}}) 318 319 err = app.SetExposed() 320 c.Assert(err, jc.ErrorIsNil) 321 } 322 323 func (s *InstanceModeSuite) TestStartWithPartialState(c *gc.C) { 324 m, err := s.State.AddMachine("quantal", state.JobHostUnits) 325 c.Assert(err, jc.ErrorIsNil) 326 inst := s.startInstance(c, m) 327 328 app := s.AddTestingService(c, "wordpress", s.charm) 329 err = app.SetExposed() 330 c.Assert(err, jc.ErrorIsNil) 331 332 // Starting the firewaller, no open ports. 333 fw, err := firewaller.NewFirewaller(s.firewaller) 334 c.Assert(err, jc.ErrorIsNil) 335 defer statetesting.AssertKillAndWait(c, fw) 336 337 s.assertPorts(c, inst, m.Id(), nil) 338 339 // Complete steps to open port. 340 u, err := app.AddUnit() 341 c.Assert(err, jc.ErrorIsNil) 342 err = u.AssignToMachine(m) 343 c.Assert(err, jc.ErrorIsNil) 344 err = u.OpenPort("tcp", 80) 345 c.Assert(err, jc.ErrorIsNil) 346 347 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 80, "tcp"}}) 348 } 349 350 func (s *InstanceModeSuite) TestStartWithUnexposedService(c *gc.C) { 351 m, err := s.State.AddMachine("quantal", state.JobHostUnits) 352 c.Assert(err, jc.ErrorIsNil) 353 inst := s.startInstance(c, m) 354 355 app := s.AddTestingService(c, "wordpress", s.charm) 356 u, err := app.AddUnit() 357 c.Assert(err, jc.ErrorIsNil) 358 err = u.AssignToMachine(m) 359 c.Assert(err, jc.ErrorIsNil) 360 err = u.OpenPort("tcp", 80) 361 c.Assert(err, jc.ErrorIsNil) 362 363 // Starting the firewaller, no open ports. 364 fw, err := firewaller.NewFirewaller(s.firewaller) 365 c.Assert(err, jc.ErrorIsNil) 366 defer statetesting.AssertKillAndWait(c, fw) 367 368 s.assertPorts(c, inst, m.Id(), nil) 369 370 // Expose service. 371 err = app.SetExposed() 372 c.Assert(err, jc.ErrorIsNil) 373 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 80, "tcp"}}) 374 } 375 376 func (s *InstanceModeSuite) TestSetClearExposedService(c *gc.C) { 377 fw, err := firewaller.NewFirewaller(s.firewaller) 378 c.Assert(err, jc.ErrorIsNil) 379 defer statetesting.AssertKillAndWait(c, fw) 380 381 app := s.AddTestingService(c, "wordpress", s.charm) 382 383 u, m := s.addUnit(c, app) 384 inst := s.startInstance(c, m) 385 err = u.OpenPort("tcp", 80) 386 c.Assert(err, jc.ErrorIsNil) 387 err = u.OpenPort("tcp", 8080) 388 c.Assert(err, jc.ErrorIsNil) 389 390 // Not exposed service, so no open port. 391 s.assertPorts(c, inst, m.Id(), nil) 392 393 // SeExposed opens the ports. 394 err = app.SetExposed() 395 c.Assert(err, jc.ErrorIsNil) 396 397 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 80, "tcp"}, {8080, 8080, "tcp"}}) 398 399 // ClearExposed closes the ports again. 400 err = app.ClearExposed() 401 c.Assert(err, jc.ErrorIsNil) 402 403 s.assertPorts(c, inst, m.Id(), nil) 404 } 405 406 func (s *InstanceModeSuite) TestRemoveUnit(c *gc.C) { 407 fw, err := firewaller.NewFirewaller(s.firewaller) 408 c.Assert(err, jc.ErrorIsNil) 409 defer statetesting.AssertKillAndWait(c, fw) 410 411 app := s.AddTestingService(c, "wordpress", s.charm) 412 err = app.SetExposed() 413 c.Assert(err, jc.ErrorIsNil) 414 415 u1, m1 := s.addUnit(c, app) 416 inst1 := s.startInstance(c, m1) 417 err = u1.OpenPort("tcp", 80) 418 c.Assert(err, jc.ErrorIsNil) 419 420 u2, m2 := s.addUnit(c, app) 421 inst2 := s.startInstance(c, m2) 422 err = u2.OpenPort("tcp", 80) 423 c.Assert(err, jc.ErrorIsNil) 424 425 s.assertPorts(c, inst1, m1.Id(), []network.PortRange{{80, 80, "tcp"}}) 426 s.assertPorts(c, inst2, m2.Id(), []network.PortRange{{80, 80, "tcp"}}) 427 428 // Remove unit. 429 err = u1.EnsureDead() 430 c.Assert(err, jc.ErrorIsNil) 431 err = u1.Remove() 432 c.Assert(err, jc.ErrorIsNil) 433 434 s.assertPorts(c, inst1, m1.Id(), nil) 435 s.assertPorts(c, inst2, m2.Id(), []network.PortRange{{80, 80, "tcp"}}) 436 } 437 438 func (s *InstanceModeSuite) TestRemoveService(c *gc.C) { 439 fw, err := firewaller.NewFirewaller(s.firewaller) 440 c.Assert(err, jc.ErrorIsNil) 441 defer statetesting.AssertKillAndWait(c, fw) 442 443 app := s.AddTestingService(c, "wordpress", s.charm) 444 err = app.SetExposed() 445 c.Assert(err, jc.ErrorIsNil) 446 447 u, m := s.addUnit(c, app) 448 inst := s.startInstance(c, m) 449 err = u.OpenPort("tcp", 80) 450 c.Assert(err, jc.ErrorIsNil) 451 452 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 80, "tcp"}}) 453 454 // Remove service. 455 err = u.EnsureDead() 456 c.Assert(err, jc.ErrorIsNil) 457 err = u.Remove() 458 c.Assert(err, jc.ErrorIsNil) 459 err = app.Destroy() 460 c.Assert(err, jc.ErrorIsNil) 461 s.assertPorts(c, inst, m.Id(), nil) 462 } 463 464 func (s *InstanceModeSuite) TestRemoveMultipleServices(c *gc.C) { 465 fw, err := firewaller.NewFirewaller(s.firewaller) 466 c.Assert(err, jc.ErrorIsNil) 467 defer statetesting.AssertKillAndWait(c, fw) 468 469 app1 := s.AddTestingService(c, "wordpress", s.charm) 470 err = app1.SetExposed() 471 c.Assert(err, jc.ErrorIsNil) 472 473 u1, m1 := s.addUnit(c, app1) 474 inst1 := s.startInstance(c, m1) 475 err = u1.OpenPort("tcp", 80) 476 c.Assert(err, jc.ErrorIsNil) 477 478 app2 := s.AddTestingService(c, "mysql", s.charm) 479 err = app2.SetExposed() 480 c.Assert(err, jc.ErrorIsNil) 481 482 u2, m2 := s.addUnit(c, app2) 483 inst2 := s.startInstance(c, m2) 484 err = u2.OpenPort("tcp", 3306) 485 c.Assert(err, jc.ErrorIsNil) 486 487 s.assertPorts(c, inst1, m1.Id(), []network.PortRange{{80, 80, "tcp"}}) 488 s.assertPorts(c, inst2, m2.Id(), []network.PortRange{{3306, 3306, "tcp"}}) 489 490 // Remove services. 491 err = u2.EnsureDead() 492 c.Assert(err, jc.ErrorIsNil) 493 err = u2.Remove() 494 c.Assert(err, jc.ErrorIsNil) 495 err = app2.Destroy() 496 c.Assert(err, jc.ErrorIsNil) 497 498 err = u1.EnsureDead() 499 c.Assert(err, jc.ErrorIsNil) 500 err = u1.Remove() 501 c.Assert(err, jc.ErrorIsNil) 502 err = app1.Destroy() 503 c.Assert(err, jc.ErrorIsNil) 504 505 s.assertPorts(c, inst1, m1.Id(), nil) 506 s.assertPorts(c, inst2, m2.Id(), nil) 507 } 508 509 func (s *InstanceModeSuite) TestDeadMachine(c *gc.C) { 510 fw, err := firewaller.NewFirewaller(s.firewaller) 511 c.Assert(err, jc.ErrorIsNil) 512 defer statetesting.AssertKillAndWait(c, fw) 513 514 app := s.AddTestingService(c, "wordpress", s.charm) 515 err = app.SetExposed() 516 c.Assert(err, jc.ErrorIsNil) 517 518 u, m := s.addUnit(c, app) 519 inst := s.startInstance(c, m) 520 err = u.OpenPort("tcp", 80) 521 c.Assert(err, jc.ErrorIsNil) 522 523 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 80, "tcp"}}) 524 525 // Remove unit and service, also tested without. Has no effect. 526 err = u.EnsureDead() 527 c.Assert(err, jc.ErrorIsNil) 528 err = u.Remove() 529 c.Assert(err, jc.ErrorIsNil) 530 err = app.Destroy() 531 c.Assert(err, jc.ErrorIsNil) 532 533 // Kill machine. 534 err = m.Refresh() 535 c.Assert(err, jc.ErrorIsNil) 536 err = m.EnsureDead() 537 c.Assert(err, jc.ErrorIsNil) 538 539 s.assertPorts(c, inst, m.Id(), nil) 540 } 541 542 func (s *InstanceModeSuite) TestRemoveMachine(c *gc.C) { 543 fw, err := firewaller.NewFirewaller(s.firewaller) 544 c.Assert(err, jc.ErrorIsNil) 545 defer statetesting.AssertKillAndWait(c, fw) 546 547 app := s.AddTestingService(c, "wordpress", s.charm) 548 err = app.SetExposed() 549 c.Assert(err, jc.ErrorIsNil) 550 551 u, m := s.addUnit(c, app) 552 inst := s.startInstance(c, m) 553 err = u.OpenPort("tcp", 80) 554 c.Assert(err, jc.ErrorIsNil) 555 556 s.assertPorts(c, inst, m.Id(), []network.PortRange{{80, 80, "tcp"}}) 557 558 // Remove unit. 559 err = u.EnsureDead() 560 c.Assert(err, jc.ErrorIsNil) 561 err = u.Remove() 562 c.Assert(err, jc.ErrorIsNil) 563 564 // Remove machine. Nothing bad should happen, but can't 565 // assert port state since the machine must have been 566 // destroyed and we lost its reference. 567 err = m.Refresh() 568 c.Assert(err, jc.ErrorIsNil) 569 err = m.EnsureDead() 570 c.Assert(err, jc.ErrorIsNil) 571 err = m.Remove() 572 c.Assert(err, jc.ErrorIsNil) 573 } 574 575 func (s *InstanceModeSuite) TestStartWithStateOpenPortsBroken(c *gc.C) { 576 app := s.AddTestingService(c, "wordpress", s.charm) 577 err := app.SetExposed() 578 c.Assert(err, jc.ErrorIsNil) 579 u, m := s.addUnit(c, app) 580 inst := s.startInstance(c, m) 581 582 err = u.OpenPort("tcp", 80) 583 c.Assert(err, jc.ErrorIsNil) 584 585 // Nothing open without firewaller. 586 s.assertPorts(c, inst, m.Id(), nil) 587 dummy.SetInstanceBroken(inst, "OpenPorts") 588 589 // Starting the firewaller should attempt to open the ports, 590 // and fail due to the method being broken. 591 fw, err := firewaller.NewFirewaller(s.firewaller) 592 c.Assert(err, jc.ErrorIsNil) 593 594 errc := make(chan error, 1) 595 go func() { errc <- fw.Wait() }() 596 s.BackingState.StartSync() 597 select { 598 case err := <-errc: 599 c.Assert(err, gc.ErrorMatches, 600 `cannot respond to units changes for "machine-1": dummyInstance.OpenPorts is broken`) 601 case <-time.After(coretesting.LongWait): 602 fw.Kill() 603 fw.Wait() 604 c.Fatal("timed out waiting for firewaller to stop") 605 } 606 } 607 608 type GlobalModeSuite struct { 609 firewallerBaseSuite 610 } 611 612 var _ = gc.Suite(&GlobalModeSuite{}) 613 614 func (s *GlobalModeSuite) SetUpTest(c *gc.C) { 615 s.firewallerBaseSuite.setUpTest(c, config.FwGlobal) 616 } 617 618 func (s *GlobalModeSuite) TearDownTest(c *gc.C) { 619 s.firewallerBaseSuite.JujuConnSuite.TearDownTest(c) 620 } 621 622 func (s *GlobalModeSuite) TestStartStop(c *gc.C) { 623 fw, err := firewaller.NewFirewaller(s.firewaller) 624 c.Assert(err, jc.ErrorIsNil) 625 statetesting.AssertKillAndWait(c, fw) 626 } 627 628 func (s *GlobalModeSuite) TestGlobalMode(c *gc.C) { 629 // Start firewaller and open ports. 630 fw, err := firewaller.NewFirewaller(s.firewaller) 631 c.Assert(err, jc.ErrorIsNil) 632 defer statetesting.AssertKillAndWait(c, fw) 633 634 app1 := s.AddTestingService(c, "wordpress", s.charm) 635 err = app1.SetExposed() 636 c.Assert(err, jc.ErrorIsNil) 637 638 u1, m1 := s.addUnit(c, app1) 639 s.startInstance(c, m1) 640 err = u1.OpenPorts("tcp", 80, 90) 641 c.Assert(err, jc.ErrorIsNil) 642 err = u1.OpenPort("tcp", 8080) 643 c.Assert(err, jc.ErrorIsNil) 644 645 app2 := s.AddTestingService(c, "moinmoin", s.charm) 646 c.Assert(err, jc.ErrorIsNil) 647 err = app2.SetExposed() 648 c.Assert(err, jc.ErrorIsNil) 649 650 u2, m2 := s.addUnit(c, app2) 651 s.startInstance(c, m2) 652 err = u2.OpenPorts("tcp", 80, 90) 653 c.Assert(err, jc.ErrorIsNil) 654 655 s.assertEnvironPorts(c, []network.PortRange{{80, 90, "tcp"}, {8080, 8080, "tcp"}}) 656 657 // Closing a port opened by a different unit won't touch the environment. 658 err = u1.ClosePorts("tcp", 80, 90) 659 c.Assert(err, jc.ErrorIsNil) 660 s.assertEnvironPorts(c, []network.PortRange{{80, 90, "tcp"}, {8080, 8080, "tcp"}}) 661 662 // Closing a port used just once changes the environment. 663 err = u1.ClosePort("tcp", 8080) 664 c.Assert(err, jc.ErrorIsNil) 665 s.assertEnvironPorts(c, []network.PortRange{{80, 90, "tcp"}}) 666 667 // Closing the last port also modifies the environment. 668 err = u2.ClosePorts("tcp", 80, 90) 669 c.Assert(err, jc.ErrorIsNil) 670 s.assertEnvironPorts(c, nil) 671 } 672 673 func (s *GlobalModeSuite) TestStartWithUnexposedService(c *gc.C) { 674 m, err := s.State.AddMachine("quantal", state.JobHostUnits) 675 c.Assert(err, jc.ErrorIsNil) 676 s.startInstance(c, m) 677 678 app := s.AddTestingService(c, "wordpress", s.charm) 679 u, err := app.AddUnit() 680 c.Assert(err, jc.ErrorIsNil) 681 err = u.AssignToMachine(m) 682 c.Assert(err, jc.ErrorIsNil) 683 err = u.OpenPort("tcp", 80) 684 c.Assert(err, jc.ErrorIsNil) 685 686 // Starting the firewaller, no open ports. 687 fw, err := firewaller.NewFirewaller(s.firewaller) 688 c.Assert(err, jc.ErrorIsNil) 689 defer statetesting.AssertKillAndWait(c, fw) 690 691 s.assertEnvironPorts(c, nil) 692 693 // Expose service. 694 err = app.SetExposed() 695 c.Assert(err, jc.ErrorIsNil) 696 s.assertEnvironPorts(c, []network.PortRange{{80, 80, "tcp"}}) 697 } 698 699 func (s *GlobalModeSuite) TestRestart(c *gc.C) { 700 // Start firewaller and open ports. 701 fw, err := firewaller.NewFirewaller(s.firewaller) 702 c.Assert(err, jc.ErrorIsNil) 703 704 app := s.AddTestingService(c, "wordpress", s.charm) 705 err = app.SetExposed() 706 c.Assert(err, jc.ErrorIsNil) 707 708 u, m := s.addUnit(c, app) 709 s.startInstance(c, m) 710 err = u.OpenPorts("tcp", 80, 90) 711 c.Assert(err, jc.ErrorIsNil) 712 err = u.OpenPort("tcp", 8080) 713 c.Assert(err, jc.ErrorIsNil) 714 715 s.assertEnvironPorts(c, []network.PortRange{{80, 90, "tcp"}, {8080, 8080, "tcp"}}) 716 717 // Stop firewaller and close one and open a different port. 718 err = worker.Stop(fw) 719 c.Assert(err, jc.ErrorIsNil) 720 721 err = u.ClosePort("tcp", 8080) 722 c.Assert(err, jc.ErrorIsNil) 723 err = u.OpenPort("tcp", 8888) 724 c.Assert(err, jc.ErrorIsNil) 725 726 // Start firewaller and check port. 727 fw, err = firewaller.NewFirewaller(s.firewaller) 728 c.Assert(err, jc.ErrorIsNil) 729 defer statetesting.AssertKillAndWait(c, fw) 730 731 s.assertEnvironPorts(c, []network.PortRange{{80, 90, "tcp"}, {8888, 8888, "tcp"}}) 732 } 733 734 func (s *GlobalModeSuite) TestRestartUnexposedService(c *gc.C) { 735 // Start firewaller and open ports. 736 fw, err := firewaller.NewFirewaller(s.firewaller) 737 c.Assert(err, jc.ErrorIsNil) 738 739 app := s.AddTestingService(c, "wordpress", s.charm) 740 err = app.SetExposed() 741 c.Assert(err, jc.ErrorIsNil) 742 743 u, m := s.addUnit(c, app) 744 s.startInstance(c, m) 745 err = u.OpenPort("tcp", 80) 746 c.Assert(err, jc.ErrorIsNil) 747 err = u.OpenPort("tcp", 8080) 748 c.Assert(err, jc.ErrorIsNil) 749 750 s.assertEnvironPorts(c, []network.PortRange{{80, 80, "tcp"}, {8080, 8080, "tcp"}}) 751 752 // Stop firewaller and clear exposed flag on service. 753 err = worker.Stop(fw) 754 c.Assert(err, jc.ErrorIsNil) 755 756 err = app.ClearExposed() 757 c.Assert(err, jc.ErrorIsNil) 758 759 // Start firewaller and check port. 760 fw, err = firewaller.NewFirewaller(s.firewaller) 761 c.Assert(err, jc.ErrorIsNil) 762 defer statetesting.AssertKillAndWait(c, fw) 763 764 s.assertEnvironPorts(c, nil) 765 } 766 767 func (s *GlobalModeSuite) TestRestartPortCount(c *gc.C) { 768 // Start firewaller and open ports. 769 fw, err := firewaller.NewFirewaller(s.firewaller) 770 c.Assert(err, jc.ErrorIsNil) 771 772 app1 := s.AddTestingService(c, "wordpress", s.charm) 773 err = app1.SetExposed() 774 c.Assert(err, jc.ErrorIsNil) 775 776 u1, m1 := s.addUnit(c, app1) 777 s.startInstance(c, m1) 778 err = u1.OpenPort("tcp", 80) 779 c.Assert(err, jc.ErrorIsNil) 780 err = u1.OpenPort("tcp", 8080) 781 c.Assert(err, jc.ErrorIsNil) 782 783 s.assertEnvironPorts(c, []network.PortRange{{80, 80, "tcp"}, {8080, 8080, "tcp"}}) 784 785 // Stop firewaller and add another service using the port. 786 err = worker.Stop(fw) 787 c.Assert(err, jc.ErrorIsNil) 788 789 app2 := s.AddTestingService(c, "moinmoin", s.charm) 790 err = app2.SetExposed() 791 c.Assert(err, jc.ErrorIsNil) 792 793 u2, m2 := s.addUnit(c, app2) 794 s.startInstance(c, m2) 795 err = u2.OpenPort("tcp", 80) 796 c.Assert(err, jc.ErrorIsNil) 797 798 // Start firewaller and check port. 799 fw, err = firewaller.NewFirewaller(s.firewaller) 800 c.Assert(err, jc.ErrorIsNil) 801 defer statetesting.AssertKillAndWait(c, fw) 802 803 s.assertEnvironPorts(c, []network.PortRange{{80, 80, "tcp"}, {8080, 8080, "tcp"}}) 804 805 // Closing a port opened by a different unit won't touch the environment. 806 err = u1.ClosePort("tcp", 80) 807 c.Assert(err, jc.ErrorIsNil) 808 s.assertEnvironPorts(c, []network.PortRange{{80, 80, "tcp"}, {8080, 8080, "tcp"}}) 809 810 // Closing a port used just once changes the environment. 811 err = u1.ClosePort("tcp", 8080) 812 c.Assert(err, jc.ErrorIsNil) 813 s.assertEnvironPorts(c, []network.PortRange{{80, 80, "tcp"}}) 814 815 // Closing the last port also modifies the environment. 816 err = u2.ClosePort("tcp", 80) 817 c.Assert(err, jc.ErrorIsNil) 818 s.assertEnvironPorts(c, nil) 819 } 820 821 type NoneModeSuite struct { 822 firewallerBaseSuite 823 } 824 825 var _ = gc.Suite(&NoneModeSuite{}) 826 827 func (s *NoneModeSuite) SetUpTest(c *gc.C) { 828 s.firewallerBaseSuite.setUpTest(c, config.FwNone) 829 } 830 831 func (s *NoneModeSuite) TestStopImmediately(c *gc.C) { 832 fw, err := firewaller.NewFirewaller(s.firewaller) 833 c.Assert(err, jc.ErrorIsNil) 834 err = workertest.CheckKilled(c, fw) 835 c.Check(err, jc.ErrorIsNil) 836 }