github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/initialize_test.go (about) 1 // Copyright Canonical Ltd. 2013 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "github.com/juju/clock" 8 mgotesting "github.com/juju/mgo/v3/testing" 9 "github.com/juju/names/v5" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/cloud" 14 "github.com/juju/juju/controller" 15 "github.com/juju/juju/core/constraints" 16 "github.com/juju/juju/core/network" 17 "github.com/juju/juju/core/permission" 18 environscloudspec "github.com/juju/juju/environs/cloudspec" 19 "github.com/juju/juju/environs/config" 20 "github.com/juju/juju/state" 21 statetesting "github.com/juju/juju/state/testing" 22 "github.com/juju/juju/storage" 23 "github.com/juju/juju/storage/poolmanager" 24 "github.com/juju/juju/storage/provider/dummy" 25 "github.com/juju/juju/testing" 26 ) 27 28 type InitializeSuite struct { 29 mgotesting.MgoSuite 30 testing.BaseSuite 31 Pool *state.StatePool 32 State *state.State 33 Model *state.Model 34 } 35 36 var _ = gc.Suite(&InitializeSuite{}) 37 38 func (s *InitializeSuite) SetUpSuite(c *gc.C) { 39 s.BaseSuite.SetUpSuite(c) 40 s.MgoSuite.SetUpSuite(c) 41 } 42 43 func (s *InitializeSuite) TearDownSuite(c *gc.C) { 44 s.MgoSuite.TearDownSuite(c) 45 s.BaseSuite.TearDownSuite(c) 46 } 47 48 func (s *InitializeSuite) SetUpTest(c *gc.C) { 49 s.BaseSuite.SetUpTest(c) 50 s.MgoSuite.SetUpTest(c) 51 } 52 53 func (s *InitializeSuite) openState(c *gc.C, modelTag names.ModelTag) { 54 pool, err := state.OpenStatePool(state.OpenParams{ 55 Clock: clock.WallClock, 56 ControllerTag: testing.ControllerTag, 57 ControllerModelTag: modelTag, 58 MongoSession: s.Session, 59 }) 60 c.Assert(err, jc.ErrorIsNil) 61 st, err := pool.SystemState() 62 c.Assert(err, jc.ErrorIsNil) 63 s.Pool = pool 64 s.State = st 65 66 m, err := st.Model() 67 c.Assert(err, jc.ErrorIsNil) 68 s.Model = m 69 } 70 71 func (s *InitializeSuite) TearDownTest(c *gc.C) { 72 if s.Pool != nil { 73 err := s.Pool.Close() 74 c.Check(err, jc.ErrorIsNil) 75 } 76 s.MgoSuite.TearDownTest(c) 77 s.BaseSuite.TearDownTest(c) 78 } 79 80 func (s *InitializeSuite) TestInitialize(c *gc.C) { 81 cfg := testing.ModelConfig(c) 82 uuid := cfg.UUID() 83 owner := names.NewLocalUserTag("initialize-admin") 84 85 userPassCredentialTag := names.NewCloudCredentialTag( 86 "dummy/" + owner.Id() + "/some-credential", 87 ) 88 emptyCredentialTag := names.NewCloudCredentialTag( 89 "dummy/" + owner.Id() + "/empty-credential", 90 ) 91 userpassCredential := cloud.NewCredential( 92 cloud.UserPassAuthType, 93 map[string]string{ 94 "username": "alice", 95 "password": "hunter2", 96 }, 97 ) 98 userpassCredential.Label = userPassCredentialTag.Name() 99 expectedUserpassCredential := statetesting.CloudCredential( 100 cloud.UserPassAuthType, 101 map[string]string{ 102 "username": "alice", 103 "password": "hunter2", 104 }, 105 ) 106 expectedUserpassCredential.DocID = "dummy#initialize-admin#some-credential" 107 expectedUserpassCredential.Owner = "initialize-admin" 108 expectedUserpassCredential.Cloud = "dummy" 109 expectedUserpassCredential.Name = "some-credential" 110 111 emptyCredential := cloud.NewEmptyCredential() 112 emptyCredential.Label = emptyCredentialTag.Name() 113 expectedEmptyCredential := statetesting.NewEmptyCredential() 114 expectedEmptyCredential.DocID = "dummy#initialize-admin#empty-credential" 115 expectedEmptyCredential.Owner = "initialize-admin" 116 expectedEmptyCredential.Cloud = "dummy" 117 expectedEmptyCredential.Name = "empty-credential" 118 119 cloudCredentialsIn := map[names.CloudCredentialTag]cloud.Credential{ 120 userPassCredentialTag: userpassCredential, 121 emptyCredentialTag: emptyCredential, 122 } 123 controllerCfg := testing.FakeControllerConfig() 124 125 ctlr, err := state.Initialize(state.InitializeParams{ 126 Clock: clock.WallClock, 127 ControllerConfig: controllerCfg, 128 ControllerModelArgs: state.ModelArgs{ 129 Type: state.ModelTypeIAAS, 130 Owner: owner, 131 Config: cfg, 132 CloudName: "dummy", 133 CloudRegion: "dummy-region", 134 CloudCredential: userPassCredentialTag, 135 StorageProviderRegistry: storage.StaticProviderRegistry{}, 136 }, 137 Cloud: cloud.Cloud{ 138 Name: "dummy", 139 Type: "dummy", 140 AuthTypes: []cloud.AuthType{ 141 cloud.EmptyAuthType, cloud.UserPassAuthType, 142 }, 143 Regions: []cloud.Region{{Name: "dummy-region"}}, 144 }, 145 CloudCredentials: cloudCredentialsIn, 146 MongoSession: s.Session, 147 AdminPassword: "dummy-secret", 148 }) 149 c.Assert(err, jc.ErrorIsNil) 150 c.Assert(ctlr, gc.NotNil) 151 st, err := ctlr.SystemState() 152 c.Assert(err, jc.ErrorIsNil) 153 m, err := st.Model() 154 c.Assert(err, jc.ErrorIsNil) 155 modelTag := m.ModelTag() 156 c.Assert(modelTag.Id(), gc.Equals, uuid) 157 158 err = ctlr.Close() 159 c.Assert(err, jc.ErrorIsNil) 160 161 s.openState(c, modelTag) 162 163 cfg, err = s.Model.ModelConfig() 164 c.Assert(err, jc.ErrorIsNil) 165 expected := cfg.AllAttrs() 166 for k, v := range config.ConfigDefaults() { 167 if _, ok := expected[k]; !ok { 168 expected[k] = v 169 } 170 } 171 c.Assert(cfg.AllAttrs(), jc.DeepEquals, expected) 172 // Check that the model has been created. 173 model, err := s.State.Model() 174 c.Assert(err, jc.ErrorIsNil) 175 c.Assert(model.Tag(), gc.Equals, modelTag) 176 c.Assert(model.CloudRegion(), gc.Equals, "dummy-region") 177 // Check that the owner has been created. 178 c.Assert(model.Owner(), gc.Equals, owner) 179 // Check that the owner can be retrieved by the tag. 180 entity, err := s.State.FindEntity(model.Owner()) 181 c.Assert(err, jc.ErrorIsNil) 182 c.Assert(entity.Tag(), gc.Equals, owner) 183 // Check that the owner has an ModelUser created for the bootstrapped model. 184 modelUser, err := s.State.UserAccess(model.Owner(), model.Tag()) 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(modelUser.UserTag, gc.Equals, owner) 187 c.Assert(modelUser.Object, gc.Equals, model.Tag()) 188 189 // Check that the model can be found through the tag. 190 entity, err = s.State.FindEntity(modelTag) 191 c.Assert(err, jc.ErrorIsNil) 192 cons, err := s.State.ModelConstraints() 193 c.Assert(err, jc.ErrorIsNil) 194 c.Assert(&cons, jc.Satisfies, constraints.IsEmpty) 195 196 addrs, err := s.State.APIHostPortsForClients() 197 c.Assert(err, jc.ErrorIsNil) 198 c.Assert(addrs, gc.HasLen, 0) 199 200 info, err := s.State.ControllerInfo() 201 c.Assert(err, jc.ErrorIsNil) 202 c.Assert(info, jc.DeepEquals, &state.ControllerInfo{ModelTag: modelTag, CloudName: "dummy"}) 203 204 // Check that the model's cloud and credential names are as 205 // expected, and the owner's cloud credentials are initialised. 206 c.Assert(model.CloudName(), gc.Equals, "dummy") 207 credentialTag, ok := model.CloudCredentialTag() 208 c.Assert(ok, jc.IsTrue) 209 c.Assert(credentialTag, gc.Equals, userPassCredentialTag) 210 cred, credentialSet, err := model.CloudCredential() 211 c.Assert(err, jc.ErrorIsNil) 212 c.Assert(credentialSet, jc.IsTrue) 213 stateCred, err := s.State.CloudCredential(credentialTag) 214 c.Assert(err, jc.ErrorIsNil) 215 c.Assert(cred, jc.DeepEquals, stateCred) 216 cloudCredentials, err := s.State.CloudCredentials(model.Owner(), "dummy") 217 c.Assert(err, jc.ErrorIsNil) 218 c.Assert(cloudCredentials, jc.DeepEquals, map[string]state.Credential{ 219 "dummy/initialize-admin/some-credential": expectedUserpassCredential, 220 "dummy/initialize-admin/empty-credential": expectedEmptyCredential, 221 }) 222 223 // Check that the cloud owner has admin access. 224 access, err := s.State.GetCloudAccess("dummy", owner) 225 c.Assert(err, jc.ErrorIsNil) 226 c.Assert(access, gc.Equals, permission.AdminAccess) 227 228 // Check that the cloud's model count is initially 1. 229 cl, err := s.State.Cloud("dummy") 230 c.Assert(err, jc.ErrorIsNil) 231 232 refCount, err := state.CloudModelRefCount(s.State, cl.Name) 233 c.Assert(err, jc.ErrorIsNil) 234 c.Assert(refCount, gc.Equals, 1) 235 236 // Check that the alpha space is created. 237 _, err = s.State.SpaceByName(network.AlphaSpaceName) 238 c.Assert(err, jc.ErrorIsNil) 239 240 // Check that the bakery config is created. 241 bakeryConfig := s.State.NewBakeryConfig() 242 _, err = bakeryConfig.GetLocalUsersKey() 243 c.Assert(err, jc.ErrorIsNil) 244 _, err = bakeryConfig.GetLocalUsersThirdPartyKey() 245 c.Assert(err, jc.ErrorIsNil) 246 _, err = bakeryConfig.GetExternalUsersThirdPartyKey() 247 c.Assert(err, jc.ErrorIsNil) 248 _, err = bakeryConfig.GetOffersThirdPartyKey() 249 c.Assert(err, jc.ErrorIsNil) 250 } 251 252 func (s *InitializeSuite) TestInitializeWithInvalidCredentialType(c *gc.C) { 253 owner := names.NewLocalUserTag("initialize-admin") 254 modelCfg := testing.ModelConfig(c) 255 controllerCfg := testing.FakeControllerConfig() 256 credentialTag := names.NewCloudCredentialTag("dummy/" + owner.Id() + "/borken") 257 _, err := state.Initialize(state.InitializeParams{ 258 Clock: clock.WallClock, 259 ControllerConfig: controllerCfg, 260 ControllerModelArgs: state.ModelArgs{ 261 Type: state.ModelTypeIAAS, 262 CloudName: "dummy", 263 Owner: owner, 264 Config: modelCfg, 265 StorageProviderRegistry: storage.StaticProviderRegistry{}, 266 }, 267 Cloud: cloud.Cloud{ 268 Name: "dummy", 269 Type: "dummy", 270 AuthTypes: []cloud.AuthType{ 271 cloud.AccessKeyAuthType, cloud.OAuth1AuthType, 272 }, 273 }, 274 CloudCredentials: map[names.CloudCredentialTag]cloud.Credential{ 275 credentialTag: cloud.NewCredential(cloud.UserPassAuthType, nil), 276 }, 277 MongoSession: s.Session, 278 AdminPassword: "dummy-secret", 279 }) 280 c.Assert(err, gc.ErrorMatches, 281 `validating initialization args: validating credential "dummy/initialize-admin/borken" for cloud "dummy": supported auth-types \["access-key" "oauth1"\], "userpass" not supported`, 282 ) 283 } 284 285 func (s *InitializeSuite) TestInitializeWithControllerInheritedConfig(c *gc.C) { 286 cfg := testing.ModelConfig(c) 287 uuid := cfg.UUID() 288 initial := cfg.AllAttrs() 289 controllerInheritedConfigIn := map[string]interface{}{ 290 "charmhub-url": initial["charmhub-url"], 291 } 292 owner := names.NewLocalUserTag("initialize-admin") 293 controllerCfg := testing.FakeControllerConfig() 294 295 ctlr, err := state.Initialize(state.InitializeParams{ 296 Clock: clock.WallClock, 297 ControllerConfig: controllerCfg, 298 ControllerModelArgs: state.ModelArgs{ 299 Type: state.ModelTypeIAAS, 300 CloudName: "dummy", 301 Owner: owner, 302 Config: cfg, 303 StorageProviderRegistry: storage.StaticProviderRegistry{}, 304 }, 305 Cloud: cloud.Cloud{ 306 Name: "dummy", 307 Type: "dummy", 308 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 309 }, 310 ControllerInheritedConfig: controllerInheritedConfigIn, 311 MongoSession: s.Session, 312 AdminPassword: "dummy-secret", 313 }) 314 c.Assert(err, jc.ErrorIsNil) 315 c.Assert(ctlr, gc.NotNil) 316 st, err := ctlr.SystemState() 317 c.Assert(err, jc.ErrorIsNil) 318 m, err := st.Model() 319 c.Assert(err, jc.ErrorIsNil) 320 modelTag := m.ModelTag() 321 c.Assert(modelTag.Id(), gc.Equals, uuid) 322 323 err = ctlr.Close() 324 c.Assert(err, jc.ErrorIsNil) 325 326 s.openState(c, modelTag) 327 328 controllerInheritedConfig, err := s.State.ReadSettings(state.GlobalSettingsC, state.CloudGlobalKey("dummy")) 329 c.Assert(err, jc.ErrorIsNil) 330 c.Assert(controllerInheritedConfig.Map(), jc.DeepEquals, controllerInheritedConfigIn) 331 332 expected := cfg.AllAttrs() 333 for k, v := range config.ConfigDefaults() { 334 if _, ok := expected[k]; !ok { 335 expected[k] = v 336 } 337 } 338 // Config as read from state has resources tags coerced to a map. 339 expected["resource-tags"] = map[string]string{} 340 cfg, err = s.Model.ModelConfig() 341 c.Assert(err, jc.ErrorIsNil) 342 c.Assert(cfg.AllAttrs(), jc.DeepEquals, expected) 343 } 344 345 func (s *InitializeSuite) TestDoubleInitializeConfig(c *gc.C) { 346 cfg := testing.ModelConfig(c) 347 owner := names.NewLocalUserTag("initialize-admin") 348 349 controllerCfg := testing.FakeControllerConfig() 350 351 args := state.InitializeParams{ 352 Clock: clock.WallClock, 353 ControllerConfig: controllerCfg, 354 ControllerModelArgs: state.ModelArgs{ 355 Type: state.ModelTypeIAAS, 356 CloudName: "dummy", 357 Owner: owner, 358 Config: cfg, 359 StorageProviderRegistry: storage.StaticProviderRegistry{}, 360 }, 361 Cloud: cloud.Cloud{ 362 Name: "dummy", 363 Type: "dummy", 364 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 365 }, 366 MongoSession: s.Session, 367 AdminPassword: "dummy-secret", 368 } 369 ctlr, err := state.Initialize(args) 370 c.Assert(err, jc.ErrorIsNil) 371 err = ctlr.Close() 372 c.Check(err, jc.ErrorIsNil) 373 374 ctlr, err = state.Initialize(args) 375 c.Check(err, gc.ErrorMatches, "already initialized") 376 c.Check(ctlr, gc.IsNil) 377 } 378 379 func (s *InitializeSuite) TestModelConfigWithAdminSecret(c *gc.C) { 380 update := map[string]interface{}{"admin-secret": "foo"} 381 remove := []string{} 382 s.testBadModelConfig(c, update, remove, "admin-secret should never be written to the state") 383 } 384 385 func (s *InitializeSuite) TestModelConfigWithCAPrivateKey(c *gc.C) { 386 update := map[string]interface{}{"ca-private-key": "foo"} 387 remove := []string{} 388 s.testBadModelConfig(c, update, remove, "ca-private-key should never be written to the state") 389 } 390 391 func (s *InitializeSuite) TestModelConfigWithoutAgentVersion(c *gc.C) { 392 update := map[string]interface{}{} 393 remove := []string{"agent-version"} 394 s.testBadModelConfig(c, update, remove, "agent-version must always be set in state") 395 } 396 397 func (s *InitializeSuite) testBadModelConfig(c *gc.C, update map[string]interface{}, remove []string, expect string) { 398 good := testing.CustomModelConfig(c, testing.Attrs{"uuid": testing.ModelTag.Id()}) 399 bad, err := good.Apply(update) 400 c.Assert(err, jc.ErrorIsNil) 401 bad, err = bad.Remove(remove) 402 c.Assert(err, jc.ErrorIsNil) 403 404 owner := names.NewLocalUserTag("initialize-admin") 405 controllerCfg := testing.FakeControllerConfig() 406 407 args := state.InitializeParams{ 408 Clock: clock.WallClock, 409 ControllerConfig: controllerCfg, 410 ControllerModelArgs: state.ModelArgs{ 411 Type: state.ModelTypeIAAS, 412 CloudName: "dummy", 413 CloudRegion: "dummy-region", 414 Owner: owner, 415 Config: bad, 416 StorageProviderRegistry: storage.StaticProviderRegistry{}, 417 }, 418 Cloud: cloud.Cloud{ 419 Name: "dummy", 420 Type: "dummy", 421 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 422 Regions: []cloud.Region{{Name: "dummy-region"}}, 423 }, 424 MongoSession: s.Session, 425 AdminPassword: "dummy-secret", 426 } 427 _, err = state.Initialize(args) 428 c.Assert(err, gc.ErrorMatches, expect) 429 430 args.ControllerModelArgs.Config = good 431 ctlr, err := state.Initialize(args) 432 c.Assert(err, jc.ErrorIsNil) 433 sysState, err := ctlr.SystemState() 434 c.Assert(err, jc.ErrorIsNil) 435 modelUUID := sysState.ModelUUID() 436 ctlr.Close() 437 438 s.openState(c, names.NewModelTag(modelUUID)) 439 m, err := s.State.Model() 440 c.Assert(err, jc.ErrorIsNil) 441 442 err = m.UpdateModelConfig(update, remove) 443 c.Assert(err, gc.ErrorMatches, expect) 444 445 // ModelConfig remains inviolate. 446 cfg, err := s.Model.ModelConfig() 447 c.Assert(err, jc.ErrorIsNil) 448 goodWithDefaults, err := config.New(config.UseDefaults, good.AllAttrs()) 449 c.Assert(err, jc.ErrorIsNil) 450 c.Assert(cfg.AllAttrs(), jc.DeepEquals, goodWithDefaults.AllAttrs()) 451 } 452 453 func (s *InitializeSuite) TestCloudConfigWithForbiddenValues(c *gc.C) { 454 badAttrNames := []string{ 455 "admin-secret", 456 "ca-private-key", 457 config.AgentVersionKey, 458 } 459 for _, attr := range controller.ControllerOnlyConfigAttributes { 460 badAttrNames = append(badAttrNames, attr) 461 } 462 463 modelCfg := testing.ModelConfig(c) 464 controllerCfg := testing.FakeControllerConfig() 465 args := state.InitializeParams{ 466 Clock: clock.WallClock, 467 ControllerConfig: controllerCfg, 468 ControllerModelArgs: state.ModelArgs{ 469 Type: state.ModelTypeIAAS, 470 CloudName: "dummy", 471 Owner: names.NewLocalUserTag("initialize-admin"), 472 Config: modelCfg, 473 StorageProviderRegistry: storage.StaticProviderRegistry{}, 474 }, 475 Cloud: cloud.Cloud{ 476 Name: "dummy", 477 Type: "dummy", 478 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 479 }, 480 MongoSession: s.Session, 481 AdminPassword: "dummy-secret", 482 } 483 484 for _, badAttrName := range badAttrNames { 485 badAttrs := map[string]interface{}{badAttrName: "foo"} 486 args.ControllerInheritedConfig = badAttrs 487 _, err := state.Initialize(args) 488 c.Assert(err, gc.ErrorMatches, "local cloud config cannot contain .*") 489 } 490 } 491 492 func (s *InitializeSuite) TestInitializeWithCloudRegionConfig(c *gc.C) { 493 cfg := testing.ModelConfig(c) 494 uuid := cfg.UUID() 495 496 // Phony region-config 497 regionInheritedConfigIn := cloud.RegionConfig{ 498 "a-region": cloud.Attrs{ 499 "a-key": "a-value", 500 }, 501 "b-region": cloud.Attrs{ 502 "b-key": "b-value", 503 }, 504 } 505 owner := names.NewLocalUserTag("initialize-admin") 506 controllerCfg := testing.FakeControllerConfig() 507 508 ctlr, err := state.Initialize(state.InitializeParams{ 509 Clock: clock.WallClock, 510 ControllerConfig: controllerCfg, 511 ControllerModelArgs: state.ModelArgs{ 512 Type: state.ModelTypeIAAS, 513 CloudName: "dummy", 514 Owner: owner, 515 Config: cfg, 516 StorageProviderRegistry: storage.StaticProviderRegistry{}, 517 }, 518 Cloud: cloud.Cloud{ 519 Name: "dummy", 520 Type: "dummy", 521 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 522 RegionConfig: regionInheritedConfigIn, // Init with phony region-config 523 }, 524 MongoSession: s.Session, 525 AdminPassword: "dummy-secret", 526 }) 527 c.Assert(err, jc.ErrorIsNil) 528 c.Assert(ctlr, gc.NotNil) 529 st, err := ctlr.SystemState() 530 c.Assert(err, jc.ErrorIsNil) 531 m, err := st.Model() 532 c.Assert(err, jc.ErrorIsNil) 533 modelTag := m.ModelTag() 534 c.Assert(modelTag.Id(), gc.Equals, uuid) 535 536 err = ctlr.Close() 537 c.Assert(err, jc.ErrorIsNil) 538 539 s.openState(c, modelTag) 540 541 for k := range regionInheritedConfigIn { 542 // Query for config for each region 543 regionInheritedConfig, err := s.State.ReadSettings( 544 state.GlobalSettingsC, 545 "dummy#"+k) 546 c.Assert(err, jc.ErrorIsNil) 547 c.Assert( 548 cloud.Attrs(regionInheritedConfig.Map()), 549 jc.DeepEquals, 550 regionInheritedConfigIn[k]) 551 } 552 } 553 554 func (s *InitializeSuite) TestInitializeWithCloudRegionMisses(c *gc.C) { 555 cfg := testing.ModelConfig(c) 556 uuid := cfg.UUID() 557 controllerInheritedConfigIn := map[string]interface{}{ 558 "no-proxy": "local", 559 } 560 // Phony region-config 561 regionInheritedConfigIn := cloud.RegionConfig{ 562 "a-region": cloud.Attrs{ 563 "no-proxy": "a-value", 564 }, 565 "b-region": cloud.Attrs{ 566 "no-proxy": "b-value", 567 }, 568 } 569 owner := names.NewLocalUserTag("initialize-admin") 570 controllerCfg := testing.FakeControllerConfig() 571 572 ctlr, err := state.Initialize(state.InitializeParams{ 573 Clock: clock.WallClock, 574 ControllerConfig: controllerCfg, 575 ControllerModelArgs: state.ModelArgs{ 576 Type: state.ModelTypeIAAS, 577 CloudName: "dummy", 578 Owner: owner, 579 Config: cfg, 580 StorageProviderRegistry: storage.StaticProviderRegistry{}, 581 }, 582 Cloud: cloud.Cloud{ 583 Name: "dummy", 584 Type: "dummy", 585 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 586 RegionConfig: regionInheritedConfigIn, // Init with phony region-config 587 }, 588 ControllerInheritedConfig: controllerInheritedConfigIn, 589 MongoSession: s.Session, 590 AdminPassword: "dummy-secret", 591 }) 592 c.Assert(err, jc.ErrorIsNil) 593 c.Assert(ctlr, gc.NotNil) 594 sysState, err := ctlr.SystemState() 595 c.Assert(err, jc.ErrorIsNil) 596 m, err := sysState.Model() 597 c.Assert(err, jc.ErrorIsNil) 598 modelTag := m.ModelTag() 599 c.Assert(modelTag.Id(), gc.Equals, uuid) 600 601 err = ctlr.Close() 602 c.Assert(err, jc.ErrorIsNil) 603 604 s.openState(c, modelTag) 605 606 var attrs map[string]interface{} 607 rspec := &environscloudspec.CloudRegionSpec{Cloud: "dummy", Region: "c-region"} 608 got, err := s.State.ComposeNewModelConfig(attrs, rspec) 609 c.Check(err, jc.ErrorIsNil) 610 c.Assert(got["no-proxy"], gc.Equals, "local") 611 } 612 613 func (s *InitializeSuite) TestInitializeWithCloudRegionHits(c *gc.C) { 614 cfg := testing.ModelConfig(c) 615 uuid := cfg.UUID() 616 617 controllerInheritedConfigIn := map[string]interface{}{ 618 "no-proxy": "local", 619 } 620 // Phony region-config 621 regionInheritedConfigIn := cloud.RegionConfig{ 622 "a-region": cloud.Attrs{ 623 "no-proxy": "a-value", 624 }, 625 "b-region": cloud.Attrs{ 626 "no-proxy": "b-value", 627 }, 628 } 629 owner := names.NewLocalUserTag("initialize-admin") 630 controllerCfg := testing.FakeControllerConfig() 631 632 ctlr, err := state.Initialize(state.InitializeParams{ 633 Clock: clock.WallClock, 634 ControllerConfig: controllerCfg, 635 ControllerModelArgs: state.ModelArgs{ 636 Type: state.ModelTypeIAAS, 637 CloudName: "dummy", 638 Owner: owner, 639 Config: cfg, 640 StorageProviderRegistry: storage.StaticProviderRegistry{}, 641 }, 642 Cloud: cloud.Cloud{ 643 Name: "dummy", 644 Type: "dummy", 645 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 646 RegionConfig: regionInheritedConfigIn, // Init with phony region-config 647 }, 648 ControllerInheritedConfig: controllerInheritedConfigIn, 649 MongoSession: s.Session, 650 AdminPassword: "dummy-secret", 651 }) 652 c.Assert(err, jc.ErrorIsNil) 653 c.Assert(ctlr, gc.NotNil) 654 sysState, err := ctlr.SystemState() 655 c.Assert(err, jc.ErrorIsNil) 656 m, err := sysState.Model() 657 c.Assert(err, jc.ErrorIsNil) 658 modelTag := m.ModelTag() 659 c.Assert(modelTag.Id(), gc.Equals, uuid) 660 661 err = ctlr.Close() 662 c.Assert(err, jc.ErrorIsNil) 663 664 s.openState(c, modelTag) 665 666 var attrs map[string]interface{} 667 for r := range regionInheritedConfigIn { 668 rspec := &environscloudspec.CloudRegionSpec{Cloud: "dummy", Region: r} 669 got, err := s.State.ComposeNewModelConfig(attrs, rspec) 670 c.Check(err, jc.ErrorIsNil) 671 c.Assert(got["no-proxy"], gc.Equals, regionInheritedConfigIn[r]["no-proxy"]) 672 } 673 } 674 675 func (s *InitializeSuite) TestInitializeWithStoragePool(c *gc.C) { 676 cfg := testing.ModelConfig(c) 677 uuid := cfg.UUID() 678 679 owner := names.NewLocalUserTag("initialize-admin") 680 controllerCfg := testing.FakeControllerConfig() 681 682 staticProvider := &dummy.StorageProvider{ 683 IsDynamic: true, 684 StorageScope: storage.ScopeEnviron, 685 SupportsFunc: func(storage.StorageKind) bool { 686 return false 687 }, 688 } 689 registry := storage.StaticProviderRegistry{ 690 Providers: map[storage.ProviderType]storage.Provider{ 691 "dummy": staticProvider, 692 }, 693 } 694 ctlr, err := state.Initialize(state.InitializeParams{ 695 Clock: clock.WallClock, 696 ControllerConfig: controllerCfg, 697 ControllerModelArgs: state.ModelArgs{ 698 Type: state.ModelTypeIAAS, 699 CloudName: "dummy", 700 Owner: owner, 701 Config: cfg, 702 StorageProviderRegistry: registry, 703 }, 704 Cloud: cloud.Cloud{ 705 Name: "dummy", 706 Type: "dummy", 707 AuthTypes: []cloud.AuthType{cloud.EmptyAuthType}, 708 }, 709 MongoSession: s.Session, 710 AdminPassword: "dummy-secret", 711 StoragePools: map[string]storage.Attrs{ 712 "spool": { 713 "type": "dummy", 714 "foo": "bar", 715 }, 716 }, 717 }) 718 c.Assert(err, jc.ErrorIsNil) 719 c.Assert(ctlr, gc.NotNil) 720 sysState, err := ctlr.SystemState() 721 c.Assert(err, jc.ErrorIsNil) 722 m, err := sysState.Model() 723 c.Assert(err, jc.ErrorIsNil) 724 modelTag := m.ModelTag() 725 c.Assert(modelTag.Id(), gc.Equals, uuid) 726 727 err = ctlr.Close() 728 c.Assert(err, jc.ErrorIsNil) 729 730 s.openState(c, modelTag) 731 732 pm := poolmanager.New(state.NewStateSettings(s.State), registry) 733 storageCfg, err := pm.Get("spool") 734 c.Assert(err, jc.ErrorIsNil) 735 expectedCfg, err := storage.NewConfig("spool", "dummy", map[string]interface{}{"foo": "bar"}) 736 c.Assert(err, jc.ErrorIsNil) 737 c.Assert(storageCfg, jc.DeepEquals, expectedCfg) 738 }