github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/controller/showcontroller_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package controller_test 5 6 import ( 7 "regexp" 8 9 "github.com/juju/cmd" 10 "github.com/juju/cmd/cmdtesting" 11 "github.com/juju/errors" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/names.v2" 15 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/cmd/juju/controller" 18 "github.com/juju/juju/core/model" 19 "github.com/juju/juju/jujuclient" 20 "github.com/juju/juju/jujuclient/jujuclienttesting" 21 "github.com/juju/juju/permission" 22 ) 23 24 type ShowControllerSuite struct { 25 baseControllerSuite 26 fakeController *fakeController 27 api func(string) controller.ControllerAccessAPI 28 setAccess func(permission.Access) 29 } 30 31 var _ = gc.Suite(&ShowControllerSuite{}) 32 33 func (s *ShowControllerSuite) SetUpTest(c *gc.C) { 34 s.baseControllerSuite.SetUpTest(c) 35 s.fakeController = &fakeController{ 36 machines: map[string][]base.Machine{ 37 "ghi": { 38 {Id: "0", InstanceId: "id-0", HasVote: false, WantsVote: true, Status: "active"}, 39 {Id: "1", InstanceId: "id-1", HasVote: false, WantsVote: true, Status: "down"}, 40 {Id: "2", InstanceId: "id-2", HasVote: true, WantsVote: true, Status: "active"}, 41 {Id: "3", InstanceId: "id-3", HasVote: false, WantsVote: false, Status: "active"}, 42 }, 43 }, 44 access: permission.SuperuserAccess, 45 bestAPIVersion: 8, 46 } 47 s.api = func(controllerName string) controller.ControllerAccessAPI { 48 s.fakeController.controllerName = controllerName 49 return s.fakeController 50 } 51 s.setAccess = func(access permission.Access) { 52 s.fakeController.access = access 53 } 54 } 55 56 func (s *ShowControllerSuite) TestShowOneControllerOneInStore(c *gc.C) { 57 s.controllersYaml = `controllers: 58 mallards: 59 uuid: this-is-another-uuid 60 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 61 ca-cert: this-is-another-ca-cert 62 cloud: mallards 63 agent-version: 999.99.99 64 mongo-version: 3.5.12 65 ` 66 s.createTestClientStore(c) 67 68 s.expectedOutput = ` 69 mallards: 70 details: 71 uuid: this-is-another-uuid 72 controller-uuid: this-is-another-uuid 73 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 74 ca-cert: this-is-another-ca-cert 75 cloud: mallards 76 agent-version: 999.99.99 77 mongo-version: 3.5.12 78 models: 79 controller: 80 uuid: abc 81 model-uuid: abc 82 machine-count: 2 83 core-count: 4 84 my-model: 85 uuid: def 86 model-uuid: def 87 machine-count: 2 88 core-count: 4 89 current-model: admin/my-model 90 account: 91 user: admin 92 access: superuser 93 `[1:] 94 95 s.assertShowController(c, "mallards") 96 } 97 98 func (s *ShowControllerSuite) TestShowControllerWithPasswords(c *gc.C) { 99 s.controllersYaml = `controllers: 100 mallards: 101 uuid: this-is-another-uuid 102 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 103 ca-cert: this-is-another-ca-cert 104 cloud: mallards 105 agent-version: 999.99.99 106 mongo-version: 3.5.12 107 ` 108 s.createTestClientStore(c) 109 110 s.expectedOutput = ` 111 mallards: 112 details: 113 uuid: this-is-another-uuid 114 controller-uuid: this-is-another-uuid 115 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 116 ca-cert: this-is-another-ca-cert 117 cloud: mallards 118 agent-version: 999.99.99 119 mongo-version: 3.5.12 120 models: 121 controller: 122 uuid: abc 123 model-uuid: abc 124 machine-count: 2 125 core-count: 4 126 my-model: 127 uuid: def 128 model-uuid: def 129 machine-count: 2 130 core-count: 4 131 current-model: admin/my-model 132 account: 133 user: admin 134 access: superuser 135 password: hunter2 136 `[1:] 137 138 s.assertShowController(c, "mallards", "--show-password") 139 } 140 141 func (s *ShowControllerSuite) TestShowControllerWithBootstrapConfig(c *gc.C) { 142 s.controllersYaml = `controllers: 143 mallards: 144 uuid: this-is-another-uuid 145 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 146 ca-cert: this-is-another-ca-cert 147 cloud: mallards 148 region: mallards1 149 agent-version: 999.99.99 150 mongo-version: 3.5.12 151 ` 152 store := s.createTestClientStore(c) 153 store.BootstrapConfig["mallards"] = jujuclient.BootstrapConfig{ 154 Config: map[string]interface{}{ 155 "name": "controller", 156 "type": "maas", 157 "extra": "value", 158 }, 159 Credential: "my-credential", 160 CloudType: "maas", 161 Cloud: "mallards", 162 CloudRegion: "mallards1", 163 CloudEndpoint: "http://mallards.local/MAAS", 164 } 165 166 s.expectedOutput = ` 167 mallards: 168 details: 169 uuid: this-is-another-uuid 170 controller-uuid: this-is-another-uuid 171 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 172 ca-cert: this-is-another-ca-cert 173 cloud: mallards 174 region: mallards1 175 agent-version: 999.99.99 176 mongo-version: 3.5.12 177 models: 178 controller: 179 uuid: abc 180 model-uuid: abc 181 machine-count: 2 182 core-count: 4 183 my-model: 184 uuid: def 185 model-uuid: def 186 machine-count: 2 187 core-count: 4 188 current-model: admin/my-model 189 account: 190 user: admin 191 access: superuser 192 `[1:] 193 194 s.assertShowController(c, "mallards") 195 } 196 197 func (s *ShowControllerSuite) TestShowOneControllerManyInStore(c *gc.C) { 198 s.createTestClientStore(c) 199 200 s.expectedOutput = ` 201 aws-test: 202 details: 203 uuid: this-is-the-aws-test-uuid 204 controller-uuid: this-is-the-aws-test-uuid 205 api-endpoints: [this-is-aws-test-of-many-api-endpoints] 206 ca-cert: this-is-aws-test-ca-cert 207 cloud: aws 208 region: us-east-1 209 agent-version: 999.99.99 210 mongo-version: 3.5.12 211 controller-machines: 212 "0": 213 instance-id: id-0 214 ha-status: ha-pending 215 "1": 216 instance-id: id-1 217 ha-status: down, lost connection 218 "2": 219 instance-id: id-2 220 ha-status: ha-enabled 221 models: 222 controller: 223 uuid: ghi 224 model-uuid: ghi 225 machine-count: 2 226 core-count: 4 227 current-model: admin/controller 228 account: 229 user: admin 230 access: superuser 231 `[1:] 232 s.assertShowController(c, "aws-test") 233 } 234 235 func (s *ShowControllerSuite) TestShowSomeControllerMoreInStore(c *gc.C) { 236 s.createTestClientStore(c) 237 s.expectedOutput = ` 238 aws-test: 239 details: 240 uuid: this-is-the-aws-test-uuid 241 controller-uuid: this-is-the-aws-test-uuid 242 api-endpoints: [this-is-aws-test-of-many-api-endpoints] 243 ca-cert: this-is-aws-test-ca-cert 244 cloud: aws 245 region: us-east-1 246 agent-version: 999.99.99 247 mongo-version: 3.5.12 248 controller-machines: 249 "0": 250 instance-id: id-0 251 ha-status: ha-pending 252 "1": 253 instance-id: id-1 254 ha-status: down, lost connection 255 "2": 256 instance-id: id-2 257 ha-status: ha-enabled 258 models: 259 controller: 260 uuid: ghi 261 model-uuid: ghi 262 machine-count: 2 263 core-count: 4 264 current-model: admin/controller 265 account: 266 user: admin 267 access: superuser 268 mark-test-prodstack: 269 details: 270 uuid: this-is-a-uuid 271 controller-uuid: this-is-a-uuid 272 api-endpoints: [this-is-one-of-many-api-endpoints] 273 ca-cert: this-is-a-ca-cert 274 cloud: prodstack 275 agent-version: 999.99.99 276 mongo-version: 3.5.12 277 account: 278 user: admin 279 access: superuser 280 `[1:] 281 282 s.assertShowController(c, "aws-test", "mark-test-prodstack") 283 } 284 285 func (s *ShowControllerSuite) TestShowOneControllerWithAPIVersionTooLow(c *gc.C) { 286 s.fakeController = &fakeController{ 287 machines: map[string][]base.Machine{}, 288 access: permission.SuperuserAccess, 289 bestAPIVersion: 1, 290 } 291 292 s.controllersYaml = `controllers: 293 mallards: 294 uuid: this-is-another-uuid 295 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 296 ca-cert: this-is-another-ca-cert 297 cloud: mallards 298 agent-version: 999.99.99 299 ` 300 s.createTestClientStore(c) 301 302 s.expectedOutput = ` 303 mallards: 304 details: 305 uuid: this-is-another-uuid 306 controller-uuid: this-is-another-uuid 307 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 308 ca-cert: this-is-another-ca-cert 309 cloud: mallards 310 agent-version: 999.99.99 311 models: 312 controller: 313 uuid: abc 314 model-uuid: abc 315 machine-count: 2 316 core-count: 4 317 my-model: 318 uuid: def 319 model-uuid: def 320 machine-count: 2 321 core-count: 4 322 current-model: admin/my-model 323 account: 324 user: admin 325 access: superuser 326 `[1:] 327 328 s.assertShowController(c, "mallards") 329 } 330 331 func (s *ShowControllerSuite) TestShowControllerJsonOne(c *gc.C) { 332 s.createTestClientStore(c) 333 334 s.expectedOutput = ` 335 {"aws-test":{"details":{"uuid":"this-is-the-aws-test-uuid","api-endpoints":["this-is-aws-test-of-many-api-endpoints"],"ca-cert":"this-is-aws-test-ca-cert","cloud":"aws","region":"us-east-1","agent-version":"999.99.99","mongo-version":"3.5.12"},"controller-machines":{"0":{"instance-id":"id-0","ha-status":"ha-pending"},"1":{"instance-id":"id-1","ha-status":"down, lost connection"},"2":{"instance-id":"id-2","ha-status":"ha-enabled"}},"models":{"controller":{"uuid":"ghi","machine-count":2,"core-count":4}},"current-model":"admin/controller","account":{"user":"admin","access":"superuser"}}} 336 `[1:] 337 338 s.assertShowController(c, "--format", "json", "aws-test") 339 } 340 341 func (s *ShowControllerSuite) TestShowControllerJsonMany(c *gc.C) { 342 s.createTestClientStore(c) 343 s.expectedOutput = ` 344 {"aws-test":{"details":{"uuid":"this-is-the-aws-test-uuid","api-endpoints":["this-is-aws-test-of-many-api-endpoints"],"ca-cert":"this-is-aws-test-ca-cert","cloud":"aws","region":"us-east-1","agent-version":"999.99.99","mongo-version":"3.5.12"},"controller-machines":{"0":{"instance-id":"id-0","ha-status":"ha-pending"},"1":{"instance-id":"id-1","ha-status":"down, lost connection"},"2":{"instance-id":"id-2","ha-status":"ha-enabled"}},"models":{"controller":{"uuid":"ghi","machine-count":2,"core-count":4}},"current-model":"admin/controller","account":{"user":"admin","access":"superuser"}},"mark-test-prodstack":{"details":{"uuid":"this-is-a-uuid","api-endpoints":["this-is-one-of-many-api-endpoints"],"ca-cert":"this-is-a-ca-cert","cloud":"prodstack","agent-version":"999.99.99","mongo-version":"3.5.12"},"account":{"user":"admin","access":"superuser"}}} 345 `[1:] 346 s.assertShowController(c, "--format", "json", "aws-test", "mark-test-prodstack") 347 } 348 349 func (s *ShowControllerSuite) TestShowControllerReadFromStoreErr(c *gc.C) { 350 s.createTestClientStore(c) 351 352 msg := "fail getting controller" 353 errStore := jujuclienttesting.NewStubStore() 354 errStore.SetErrors(errors.New(msg)) 355 s.store = errStore 356 s.expectedErr = msg 357 358 s.assertShowControllerFailed(c, "test1") 359 errStore.CheckCallNames(c, "ControllerByName") 360 } 361 362 func (s *ShowControllerSuite) TestShowControllerNoArgs(c *gc.C) { 363 store := s.createTestClientStore(c) 364 store.CurrentControllerName = "aws-test" 365 366 s.expectedOutput = ` 367 {"aws-test":{"details":{"uuid":"this-is-the-aws-test-uuid","api-endpoints":["this-is-aws-test-of-many-api-endpoints"],"ca-cert":"this-is-aws-test-ca-cert","cloud":"aws","region":"us-east-1","agent-version":"999.99.99","mongo-version":"3.5.12"},"controller-machines":{"0":{"instance-id":"id-0","ha-status":"ha-pending"},"1":{"instance-id":"id-1","ha-status":"down, lost connection"},"2":{"instance-id":"id-2","ha-status":"ha-enabled"}},"models":{"controller":{"uuid":"ghi","machine-count":2,"core-count":4}},"current-model":"admin/controller","account":{"user":"admin","access":"superuser"}}} 368 `[1:] 369 s.assertShowController(c, "--format", "json") 370 } 371 372 func (s *ShowControllerSuite) TestShowControllerNoArgsNoCurrent(c *gc.C) { 373 store := s.createTestClientStore(c) 374 store.CurrentControllerName = "" 375 s.expectedErr = regexp.QuoteMeta(`there is no active controller`) 376 s.assertShowControllerFailed(c) 377 } 378 379 func (s *ShowControllerSuite) TestShowControllerNotFound(c *gc.C) { 380 s.createTestClientStore(c) 381 382 s.expectedErr = `controller whoops not found` 383 s.assertShowControllerFailed(c, "whoops") 384 } 385 386 func (s *ShowControllerSuite) TestShowControllerUnrecognizedFlag(c *gc.C) { 387 s.expectedErr = `option provided but not defined: -m` 388 s.assertShowControllerFailed(c, "-m", "my.world") 389 } 390 391 func (s *ShowControllerSuite) TestShowControllerUnrecognizedOptionFlag(c *gc.C) { 392 s.expectedErr = `option provided but not defined: --model` 393 s.assertShowControllerFailed(c, "--model", "still.my.world") 394 } 395 396 func (s *ShowControllerSuite) TestShowControllerRefreshesStore(c *gc.C) { 397 store := s.createTestClientStore(c) 398 _, err := s.runShowController(c, "aws-test") 399 c.Assert(err, jc.ErrorIsNil) 400 c.Check(store.Controllers["aws-test"].ActiveControllerMachineCount, gc.Equals, 1) 401 s.fakeController.machines["ghi"][0].HasVote = true 402 _, err = s.runShowController(c, "aws-test") 403 c.Assert(err, jc.ErrorIsNil) 404 c.Check(store.Controllers["aws-test"].ControllerMachineCount, gc.Equals, 3) 405 c.Check(store.Controllers["aws-test"].ActiveControllerMachineCount, gc.Equals, 2) 406 } 407 408 func (s *ShowControllerSuite) TestShowControllerRefreshesStoreModels(c *gc.C) { 409 store := s.createTestClientStore(c) 410 c.Assert(store.Models["mallards"], gc.DeepEquals, &jujuclient.ControllerModels{ 411 CurrentModel: "admin/my-model", 412 Models: map[string]jujuclient.ModelDetails{ 413 "model0": {ModelUUID: "abc", ModelType: model.IAAS}, 414 "my-model": {ModelUUID: "def", ModelType: model.IAAS}, 415 }, 416 }) 417 _, err := s.runShowController(c, "mallards") 418 c.Assert(err, jc.ErrorIsNil) 419 c.Assert(store.Models["mallards"], gc.DeepEquals, &jujuclient.ControllerModels{ 420 CurrentModel: "admin/my-model", 421 Models: map[string]jujuclient.ModelDetails{ 422 "admin/controller": {ModelUUID: "abc", ModelType: model.IAAS}, 423 "admin/my-model": {ModelUUID: "def", ModelType: model.IAAS}, 424 }, 425 }) 426 } 427 428 func (s *ShowControllerSuite) TestShowControllerForUserWithLoginAccess(c *gc.C) { 429 s.controllersYaml = `controllers: 430 mallards: 431 uuid: this-is-another-uuid 432 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 433 ca-cert: this-is-another-ca-cert 434 cloud: mallards 435 agent-version: 999.99.99 436 ` 437 s.expectedOutput = ` 438 mallards: 439 details: 440 uuid: this-is-another-uuid 441 controller-uuid: this-is-another-uuid 442 api-endpoints: [this-is-another-of-many-api-endpoints, this-is-one-more-of-many-api-endpoints] 443 ca-cert: this-is-another-ca-cert 444 cloud: mallards 445 agent-version: 999.99.99 446 current-model: admin/my-model 447 account: 448 user: admin 449 access: login 450 `[1:] 451 452 store := s.createTestClientStore(c) 453 c.Assert(store.Models["mallards"].Models, gc.HasLen, 2) 454 s.setAccess(permission.LoginAccess) 455 s.assertShowController(c, "mallards") 456 } 457 458 func (s *ShowControllerSuite) TestShowControllerWithIdentityProvider(c *gc.C) { 459 _ = s.createTestClientStore(c) 460 ctx, err := s.runShowController(c, "aws-test") 461 c.Assert(err, jc.ErrorIsNil) 462 c.Assert(cmdtesting.Stdout(ctx), gc.Not(jc.Contains), "identity-url") 463 464 expURL := "https://api.jujucharms.com/identity" 465 s.fakeController.identityURL = expURL 466 ctx, err = s.runShowController(c, "aws-test") 467 c.Assert(err, jc.ErrorIsNil) 468 c.Assert(cmdtesting.Stdout(ctx), jc.Contains, "identity-url: "+expURL) 469 } 470 471 func (s *ShowControllerSuite) runShowController(c *gc.C, args ...string) (*cmd.Context, error) { 472 return cmdtesting.RunCommand(c, controller.NewShowControllerCommandForTest(s.store, s.api), args...) 473 } 474 475 func (s *ShowControllerSuite) assertShowControllerFailed(c *gc.C, args ...string) { 476 _, err := s.runShowController(c, args...) 477 c.Assert(err, gc.ErrorMatches, s.expectedErr) 478 } 479 480 func (s *ShowControllerSuite) assertShowController(c *gc.C, args ...string) { 481 context, err := s.runShowController(c, args...) 482 c.Assert(err, jc.ErrorIsNil) 483 c.Assert(cmdtesting.Stdout(context), gc.Equals, s.expectedOutput) 484 } 485 486 type fakeController struct { 487 controllerName string 488 machines map[string][]base.Machine 489 access permission.Access 490 bestAPIVersion int 491 identityURL string 492 } 493 494 func (c *fakeController) GetControllerAccess(user string) (permission.Access, error) { 495 return c.access, nil 496 } 497 498 func (*fakeController) ModelConfig() (map[string]interface{}, error) { 499 return map[string]interface{}{"agent-version": "999.99.99"}, nil 500 } 501 502 func (c *fakeController) ModelStatus(models ...names.ModelTag) (result []base.ModelStatus, _ error) { 503 for _, mtag := range models { 504 result = append(result, base.ModelStatus{ 505 UUID: mtag.Id(), 506 TotalMachineCount: 2, 507 CoreCount: 4, 508 Machines: c.machines[mtag.Id()], 509 }) 510 } 511 return result, nil 512 } 513 514 func (c *fakeController) MongoVersion() (string, error) { 515 if c.bestAPIVersion < 3 { 516 return "", errors.NotSupportedf("requires APIVersion >= 3") 517 } 518 return "3.5.12", nil 519 } 520 521 func (c *fakeController) AllModels() (result []base.UserModel, _ error) { 522 models := map[string][]base.UserModel{ 523 "aws-test": { 524 {Name: "controller", UUID: "ghi", Owner: "admin", Type: model.IAAS}, 525 }, 526 "mallards": { 527 {Name: "controller", UUID: "abc", Owner: "admin", Type: model.IAAS}, 528 {Name: "my-model", UUID: "def", Owner: "admin", Type: model.IAAS}, 529 }, 530 } 531 all, exists := models[c.controllerName] 532 if !exists { 533 return result, nil 534 } 535 return all, nil 536 } 537 538 func (c *fakeController) IdentityProviderURL() (string, error) { 539 return c.identityURL, nil 540 } 541 542 func (*fakeController) Close() error { 543 return nil 544 }