func (s *InitializeSuite) TestDoubleInitializeConfig(c *gc.C) { cfg := testing.EnvironConfig(c) owner := names.NewLocalUserTag("initialize-admin") mgoInfo := statetesting.NewMongoInfo() dialOpts := statetesting.NewDialOpts() st, err := state.Initialize(owner, mgoInfo, cfg, dialOpts, state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) st.Close() _, err = state.Initialize(owner, mgoInfo, cfg, dialOpts, state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "already initialized") }
func (s *environSuite) TestInvalidConfig(c *gc.C) { var oldType string oldType = s.Environ.Config().AllAttrs()["type"].(string) // Create an invalid config by taking the current config and // tweaking the provider type. info := s.MongoInfo(c) opts := mongo.DefaultDialOpts() st2, err := state.Open(info, opts, state.Policy(nil)) c.Assert(err, gc.IsNil) defer st2.Close() err = st2.UpdateEnvironConfig(map[string]interface{}{"type": "unknown"}, nil, nil) c.Assert(err, gc.IsNil) w := st2.WatchForEnvironConfigChanges() defer stopWatcher(c, w) done := make(chan environs.Environ) go func() { env, err := worker.WaitForEnviron(w, st2, nil) c.Check(err, gc.IsNil) done <- env }() // Wait for the loop to process the invalid configuratrion <-worker.LoadedInvalid st2.UpdateEnvironConfig(map[string]interface{}{ "type": oldType, "secret": "environ_test", }, nil, nil) env := <-done c.Assert(env, gc.NotNil) c.Assert(env.Config().AllAttrs()["secret"], gc.Equals, "environ_test") }
// fixEnvironment undoes the work of invalidateEnvironment. func (s *CommonProvisionerSuite) fixEnvironment(c *gc.C) error { st, err := state.Open(s.MongoInfo(c), mongo.DefaultDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) defer st.Close() attrs := map[string]interface{}{"type": s.cfg.AllAttrs()["type"]} return st.UpdateEnvironConfig(attrs, nil, nil) }
func (s *InitializeSuite) TestInitialize(c *gc.C) { cfg := testing.EnvironConfig(c) initial := cfg.AllAttrs() st, err := state.Initialize(state.TestingStateInfo(), cfg, state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) c.Assert(st, gc.NotNil) err = st.Close() c.Assert(err, gc.IsNil) s.openState(c) cfg, err = s.State.EnvironConfig() c.Assert(err, gc.IsNil) c.Assert(cfg.AllAttrs(), gc.DeepEquals, initial) env, err := s.State.Environment() c.Assert(err, gc.IsNil) entity, err := s.State.FindEntity("environment-" + env.UUID()) c.Assert(err, gc.IsNil) annotator := entity.(state.Annotator) annotations, err := annotator.Annotations() c.Assert(err, gc.IsNil) c.Assert(annotations, gc.HasLen, 0) cons, err := s.State.EnvironConstraints() c.Assert(err, gc.IsNil) c.Assert(&cons, jc.Satisfies, constraints.IsEmpty) addrs, err := s.State.APIHostPorts() c.Assert(err, gc.IsNil) c.Assert(addrs, gc.HasLen, 0) info, err := s.State.StateServerInfo() c.Assert(err, gc.IsNil) c.Assert(info, jc.DeepEquals, &state.StateServerInfo{}) }
// invalidateEnvironment alters the environment configuration // so the Settings returned from the watcher will not pass // validation. func (s *CommonProvisionerSuite) invalidateEnvironment(c *gc.C) { st, err := state.Open(s.MongoInfo(c), mongo.DefaultDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) defer st.Close() attrs := map[string]interface{}{"type": "unknown"} err = st.UpdateEnvironConfig(attrs, nil, nil) c.Assert(err, gc.IsNil) }
func (s *environSuite) TestEnvironmentChanges(c *gc.C) { originalConfig, err := s.State.EnvironConfig() c.Assert(err, gc.IsNil) logc := make(logChan, 1009) c.Assert(loggo.RegisterWriter("testing", logc, loggo.WARNING), gc.IsNil) defer loggo.RemoveWriter("testing") obs, err := worker.NewEnvironObserver(s.State) c.Assert(err, gc.IsNil) env := obs.Environ() c.Assert(env.Config().AllAttrs(), gc.DeepEquals, originalConfig.AllAttrs()) var oldType string oldType = env.Config().AllAttrs()["type"].(string) info := s.MongoInfo(c) opts := mongo.DefaultDialOpts() st2, err := state.Open(info, opts, state.Policy(nil)) defer st2.Close() // Change to an invalid configuration and check // that the observer's environment remains the same. st2.UpdateEnvironConfig(map[string]interface{}{"type": "invalid"}, nil, nil) st2.StartSync() // Wait for the observer to register the invalid environment timeout := time.After(coretesting.LongWait) loop: for { select { case msg := <-logc: if strings.Contains(msg, "error creating Environ") { break loop } case <-timeout: c.Fatalf("timed out waiting to see broken environment") } } // Check that the returned environ is still the same. env = obs.Environ() c.Assert(env.Config().AllAttrs(), gc.DeepEquals, originalConfig.AllAttrs()) // Change the environment back to a valid configuration // with a different name and check that we see it. st2.UpdateEnvironConfig(map[string]interface{}{"type": oldType, "name": "a-new-name"}, nil, nil) st2.StartSync() for a := coretesting.LongAttempt.Start(); a.Next(); { env := obs.Environ() if !a.HasNext() { c.Fatalf("timed out waiting for new environ") } if env.Config().Name() == "a-new-name" { break } } }
func (s *InitializeSuite) openState(c *gc.C, environTag names.EnvironTag) { st, err := state.Open( environTag, statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil), ) c.Assert(err, jc.ErrorIsNil) s.State = st }
func (s *bootstrapSuite) TestInitializeStateFailsSecondTime(c *gc.C) { dataDir := c.MkDir() configParams := agent.AgentConfigParams{ Paths: agent.Paths{DataDir: dataDir}, Tag: names.NewMachineTag("0"), UpgradedToVersion: jujuversion.Current, StateAddresses: []string{s.mgoInst.Addr()}, CACert: testing.CACert, Password: testing.DefaultMongoPassword, Model: testing.ModelTag, } cfg, err := agent.NewAgentConfig(configParams) c.Assert(err, jc.ErrorIsNil) cfg.SetStateServingInfo(params.StateServingInfo{ APIPort: 5555, StatePort: s.mgoInst.Port(), Cert: "foo", PrivateKey: "bar", SharedSecret: "baz", SystemIdentity: "qux", }) expectHW := instance.MustParseHardware("mem=2048M") mcfg := agentbootstrap.BootstrapMachineConfig{ BootstrapConstraints: constraints.MustParse("mem=1024M"), Jobs: []multiwatcher.MachineJob{multiwatcher.JobManageModel}, InstanceId: "i-bootstrap", Characteristics: expectHW, } envAttrs := dummy.SampleConfig().Delete("admin-secret").Merge(testing.Attrs{ "agent-version": jujuversion.Current.String(), }) envCfg, err := config.New(config.NoDefaults, envAttrs) c.Assert(err, jc.ErrorIsNil) hostedModelConfigAttrs := map[string]interface{}{ "name": "hosted", "uuid": utils.MustNewUUID().String(), } adminUser := names.NewLocalUserTag("agent-admin") st, _, err := agentbootstrap.InitializeState( adminUser, cfg, envCfg, hostedModelConfigAttrs, mcfg, mongo.DefaultDialOpts(), state.Policy(nil), ) c.Assert(err, jc.ErrorIsNil) st.Close() st, _, err = agentbootstrap.InitializeState(adminUser, cfg, envCfg, nil, mcfg, mongo.DefaultDialOpts(), environs.NewStatePolicy()) if err == nil { st.Close() } c.Assert(err, gc.ErrorMatches, "failed to initialize mongo admin user: cannot set admin password: not authorized .*") }
func (s *environSuite) TestErrorWhenEnvironIsInvalid(c *gc.C) { // reopen the state so that we can wangle a dodgy environ config in there. st, err := state.Open(s.MongoInfo(c), mongo.DefaultDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) defer st.Close() err = st.UpdateEnvironConfig(map[string]interface{}{"secret": 999}, nil, nil) c.Assert(err, gc.IsNil) obs, err := worker.NewEnvironObserver(s.State) c.Assert(err, gc.ErrorMatches, `cannot make Environ: secret: expected string, got int\(999\)`) c.Assert(obs, gc.IsNil) }
func (s *InitializeSuite) TestDoubleInitializeConfig(c *gc.C) { cfg := testing.EnvironConfig(c) initial := cfg.AllAttrs() st := state.TestingInitialize(c, cfg, state.Policy(nil)) st.Close() // A second initialize returns an open *State, but ignores its params. // TODO(fwereade) I think this is crazy, but it's what we were testing // for originally... cfg, err := cfg.Apply(map[string]interface{}{"authorized-keys": "something-else"}) c.Assert(err, gc.IsNil) st, err = state.Initialize(state.TestingStateInfo(), cfg, state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) c.Assert(st, gc.NotNil) st.Close() s.openState(c) cfg, err = s.State.EnvironConfig() c.Assert(err, gc.IsNil) c.Assert(cfg.AllAttrs(), gc.DeepEquals, initial) }
func (s *InitializeSuite) TestEnvironConfigWithAdminSecret(c *gc.C) { // admin-secret blocks Initialize. good := testing.EnvironConfig(c) badUpdateAttrs := map[string]interface{}{"admin-secret": "foo"} bad, err := good.Apply(badUpdateAttrs) _, err = state.Initialize(state.TestingStateInfo(), bad, state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "admin-secret should never be written to the state") // admin-secret blocks UpdateEnvironConfig. st := state.TestingInitialize(c, good, state.Policy(nil)) st.Close() s.openState(c) err = s.State.UpdateEnvironConfig(badUpdateAttrs, nil, nil) c.Assert(err, gc.ErrorMatches, "admin-secret should never be written to the state") // EnvironConfig remains inviolate. cfg, err := s.State.EnvironConfig() c.Assert(err, gc.IsNil) c.Assert(cfg.AllAttrs(), gc.DeepEquals, good.AllAttrs()) }
func (s *provisionerSuite) TestContainerManagerConfigLXC(c *gc.C) { args := params.ContainerManagerConfigParams{Type: instance.LXC} st, err := state.Open(s.MongoInfo(c), mongo.DialOpts{}, state.Policy(nil)) c.Assert(err, gc.IsNil) defer st.Close() tests := []struct { lxcUseClone bool lxcUseCloneAufs bool expectedUseClone string expectedUseCloneAufs string }{{ lxcUseClone: true, expectedUseClone: "true", expectedUseCloneAufs: "false", }, { lxcUseClone: false, expectedUseClone: "false", expectedUseCloneAufs: "false", }, { lxcUseCloneAufs: false, expectedUseClone: "false", expectedUseCloneAufs: "false", }, { lxcUseClone: true, lxcUseCloneAufs: true, expectedUseClone: "true", expectedUseCloneAufs: "true", }} result, err := s.provisioner.ContainerManagerConfig(args) c.Assert(err, gc.IsNil) c.Assert(result.ManagerConfig[container.ConfigName], gc.Equals, "juju") c.Assert(result.ManagerConfig["use-clone"], gc.Equals, "") // Change lxc-clone, and ensure it gets picked up. for i, t := range tests { c.Logf("test %d: %+v", i, t) err = st.UpdateEnvironConfig(map[string]interface{}{ "lxc-clone": t.lxcUseClone, "lxc-clone-aufs": t.lxcUseCloneAufs, }, nil, nil) c.Assert(err, gc.IsNil) result, err := s.provisioner.ContainerManagerConfig(args) c.Assert(err, gc.IsNil) c.Assert(result.ManagerConfig[container.ConfigName], gc.Equals, "juju") c.Assert(result.ManagerConfig["use-clone"], gc.Equals, t.expectedUseClone) c.Assert(result.ManagerConfig["use-aufs"], gc.Equals, t.expectedUseCloneAufs) } }
func (s *EnvironSuite) TestUUID(c *gc.C) { uuidA := s.env.UUID() c.Assert(uuidA, gc.HasLen, 36) // Check that two environments have different UUIDs. s.State.Close() s.MgoSuite.TearDownTest(c) s.MgoSuite.SetUpTest(c) s.State = state.TestingInitialize(c, nil, state.Policy(nil)) env, err := s.State.Environment() c.Assert(err, gc.IsNil) uuidB := env.UUID() c.Assert(uuidA, gc.Not(gc.Equals), uuidB) }
func (s *InitializeSuite) TestEnvironConfigWithoutAgentVersion(c *gc.C) { // admin-secret blocks Initialize. good := testing.EnvironConfig(c) attrs := good.AllAttrs() delete(attrs, "agent-version") bad, err := config.New(config.NoDefaults, attrs) c.Assert(err, gc.IsNil) _, err = state.Initialize(state.TestingStateInfo(), bad, state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "agent-version must always be set in state") st := state.TestingInitialize(c, good, state.Policy(nil)) st.Close() s.openState(c) err = s.State.UpdateEnvironConfig(map[string]interface{}{}, []string{"agent-version"}, nil) c.Assert(err, gc.ErrorMatches, "agent-version must always be set in state") // EnvironConfig remains inviolate. cfg, err := s.State.EnvironConfig() c.Assert(err, gc.IsNil) c.Assert(cfg.AllAttrs(), gc.DeepEquals, good.AllAttrs()) }
func (*NewConnSuite) TestConnStateSecretsSideEffect(c *gc.C) { attrs := dummy.SampleConfig().Merge(coretesting.Attrs{ "admin-secret": "side-effect secret", "secret": "pork", }) cfg, err := config.New(config.NoDefaults, attrs) c.Assert(err, gc.IsNil) ctx := coretesting.Context(c) env, err := environs.Prepare(cfg, ctx, configstore.NewMem()) c.Assert(err, gc.IsNil) envtesting.UploadFakeTools(c, env.Storage()) err = bootstrap.Bootstrap(ctx, env, environs.BootstrapParams{}) c.Assert(err, gc.IsNil) info, _, err := env.StateInfo() c.Assert(err, gc.IsNil) info.Password = utils.UserPasswordHash("side-effect secret", utils.CompatSalt) // Use a state without a nil policy, which will allow us to set an invalid config. st, err := state.Open(info, mongo.DefaultDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) defer assertClose(c, st) // Verify we have secrets in the environ config already. statecfg, err := st.EnvironConfig() c.Assert(err, gc.IsNil) c.Assert(statecfg.UnknownAttrs()["secret"], gc.Equals, "pork") // Remove the secret from state, and then make sure it gets // pushed back again. err = st.UpdateEnvironConfig(map[string]interface{}{}, []string{"secret"}, nil) c.Assert(err, gc.IsNil) // Make a new Conn, which will push the secrets. conn, err := juju.NewConn(env) c.Assert(err, gc.IsNil) defer assertClose(c, conn) statecfg, err = conn.State.EnvironConfig() c.Assert(err, gc.IsNil) c.Assert(statecfg.UnknownAttrs()["secret"], gc.Equals, "pork") // Reset the admin password so the state db can be reused. err = conn.State.SetAdminMongoPassword("") c.Assert(err, gc.IsNil) }
func (s *InitializeSuite) openState(c *gc.C) { st, err := state.Open(statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) s.State = st }
func (s *UnitSuite) TestSetMongoPasswordOnUnitAfterConnectingAsMachineEntity(c *gc.C) { // Make a second unit to use later. (Subordinate units can only be created // as a side-effect of a principal entering relation scope.) subUnit := s.addSubordinateUnit(c) info := state.TestingMongoInfo() st, err := state.Open(info, state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) defer st.Close() // Turn on fully-authenticated mode. err = st.SetAdminMongoPassword("admin-secret") c.Assert(err, gc.IsNil) // Add a new machine, assign the units to it // and set its password. m, err := st.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) unit, err := st.Unit(s.unit.Name()) c.Assert(err, gc.IsNil) subUnit, err = st.Unit(subUnit.Name()) c.Assert(err, gc.IsNil) err = unit.AssignToMachine(m) c.Assert(err, gc.IsNil) err = m.SetMongoPassword("foo") c.Assert(err, gc.IsNil) // Sanity check that we cannot connect with the wrong // password info.Tag = m.Tag() info.Password = "******" err = tryOpenState(info) c.Assert(err, jc.Satisfies, errors.IsUnauthorized) // Connect as the machine entity. info.Tag = m.Tag() info.Password = "******" st1, err := state.Open(info, state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) defer st1.Close() // Change the password for a unit derived from // the machine entity's state. unit, err = st1.Unit(s.unit.Name()) c.Assert(err, gc.IsNil) err = unit.SetMongoPassword("bar") c.Assert(err, gc.IsNil) // Now connect as the unit entity and, as that // that entity, change the password for a new unit. info.Tag = unit.Tag() info.Password = "******" st2, err := state.Open(info, state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) defer st2.Close() // Check that we can set its password. unit, err = st2.Unit(subUnit.Name()) c.Assert(err, gc.IsNil) err = unit.SetMongoPassword("bar2") c.Assert(err, gc.IsNil) // Clear the admin password, so tests can reset the db. err = st.SetAdminMongoPassword("") c.Assert(err, gc.IsNil) }
func (s *InitializeSuite) TestModelConfigWithoutAgentVersion(c *gc.C) { // admin-secret blocks Initialize. good := testing.ModelConfig(c) attrs := good.AllAttrs() delete(attrs, "agent-version") bad, err := config.New(config.NoDefaults, attrs) c.Assert(err, jc.ErrorIsNil) owner := names.NewLocalUserTag("initialize-admin") _, err = state.Initialize(owner, statetesting.NewMongoInfo(), bad, statetesting.NewDialOpts(), state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "agent-version must always be set in state") st := statetesting.Initialize(c, owner, good, nil) // yay side effects st.Close() s.openState(c, st.ModelTag()) err = s.State.UpdateModelConfig(map[string]interface{}{}, []string{"agent-version"}, nil) c.Assert(err, gc.ErrorMatches, "agent-version must always be set in state") // ModelConfig remains inviolate. cfg, err := s.State.ModelConfig() c.Assert(err, jc.ErrorIsNil) c.Assert(cfg.AllAttrs(), gc.DeepEquals, good.AllAttrs()) }
func (s *InitializeSuite) TestModelConfigWithAdminSecret(c *gc.C) { // admin-secret blocks Initialize. good := testing.ModelConfig(c) badUpdateAttrs := map[string]interface{}{"admin-secret": "foo"} bad, err := good.Apply(badUpdateAttrs) owner := names.NewLocalUserTag("initialize-admin") _, err = state.Initialize(owner, statetesting.NewMongoInfo(), bad, statetesting.NewDialOpts(), state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "admin-secret should never be written to the state") // admin-secret blocks UpdateModelConfig. st := statetesting.Initialize(c, owner, good, nil) st.Close() s.openState(c, st.ModelTag()) err = s.State.UpdateModelConfig(badUpdateAttrs, nil, nil) c.Assert(err, gc.ErrorMatches, "admin-secret should never be written to the state") // ModelConfig remains inviolate. cfg, err := s.State.ModelConfig() c.Assert(err, jc.ErrorIsNil) c.Assert(cfg.AllAttrs(), gc.DeepEquals, good.AllAttrs()) }
func (s *InitializeSuite) openState(c *gc.C) { st, err := state.Open(state.TestingMongoInfo(), state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) s.State = st }
func (s *InitializeSuite) openState(c *gc.C) { var err error s.State, err = state.Open(state.TestingStateInfo(), state.TestingDialOpts(), state.Policy(nil)) c.Assert(err, gc.IsNil) }