func (s *serverSuite) TestMachineLoginStartsPinger(c *gc.C) { // This is the same steps as OpenAPIAsNewMachine but we need to assert // the agent is not alive before we actually open the API. // Create a new machine to verify "agent alive" behavior. machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("foo", "fake_nonce", nil) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) // Not alive yet. s.assertAlive(c, machine, false) // Login as the machine agent of the created machine. st := s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce") // Make sure the pinger has started. s.assertAlive(c, machine, true) // Now make sure it stops when connection is closed. c.Assert(st.Close(), gc.IsNil) // Sync, then wait for a bit to make sure the state is updated. s.State.StartSync() <-time.After(coretesting.ShortWait) s.State.StartSync() s.assertAlive(c, machine, false) }
func (s *RelationerSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) var err error s.svc = s.AddTestingService(c, "u", s.AddTestingCharm(c, "riak")) c.Assert(err, gc.IsNil) rels, err := s.svc.Relations() c.Assert(err, gc.IsNil) c.Assert(rels, gc.HasLen, 1) s.rel = rels[0] _, unit := s.AddRelationUnit(c, "u/0") s.dirPath = c.MkDir() s.dir, err = relation.ReadStateDir(s.dirPath, s.rel.Id()) c.Assert(err, gc.IsNil) s.hooks = make(chan hook.Info) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = unit.SetPassword(password) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAs(c, unit.Tag(), password) s.uniter = s.st.Uniter() c.Assert(s.uniter, gc.NotNil) apiUnit, err := s.uniter.Unit(unit.Tag()) c.Assert(err, gc.IsNil) apiRel, err := s.uniter.Relation(s.rel.Tag()) c.Assert(err, gc.IsNil) s.apiRelUnit, err = apiRel.Unit(apiUnit) c.Assert(err, gc.IsNil) }
func (s *ContextRelationSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) ch := s.AddTestingCharm(c, "riak") var err error s.svc = s.AddTestingService(c, "u", ch) rels, err := s.svc.Relations() c.Assert(err, gc.IsNil) c.Assert(rels, gc.HasLen, 1) s.rel = rels[0] unit, err := s.svc.AddUnit() c.Assert(err, gc.IsNil) s.ru, err = s.rel.Unit(unit) c.Assert(err, gc.IsNil) err = s.ru.EnterScope(nil) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = unit.SetPassword(password) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAs(c, unit.Tag(), password) s.uniter = s.st.Uniter() c.Assert(s.uniter, gc.NotNil) apiRel, err := s.uniter.Relation(s.rel.Tag()) c.Assert(err, gc.IsNil) apiUnit, err := s.uniter.Unit(unit.Tag()) c.Assert(err, gc.IsNil) s.apiRelUnit, err = apiRel.Unit(apiUnit) c.Assert(err, gc.IsNil) }
func (c *AddUserCommand) Run(ctx *cmd.Context) error { store, err := configstore.Default() if err != nil { return fmt.Errorf("cannot open environment info storage: %v", err) } storeInfo, err := store.ReadInfo(c.EnvName) if err != nil { return err } client, err := juju.NewUserManagerClient(c.EnvName) if err != nil { return err } defer client.Close() if c.GeneratePassword { c.Password, err = utils.RandomPassword() if err != nil { return fmt.Errorf("Failed to generate password: %v", err) } } outputInfo := configstore.EnvironInfoData{} outputInfo.User = c.User outputInfo.Password = c.Password outputInfo.StateServers = storeInfo.APIEndpoint().Addresses outputInfo.CACert = storeInfo.APIEndpoint().CACert err = c.out.Write(ctx, outputInfo) if err != nil { return err } return client.AddUser(c.User, c.Password) }
func (s *HookContextSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) var err error sch := s.AddTestingCharm(c, "wordpress") s.service = s.AddTestingService(c, "u", sch) s.unit = s.AddUnit(c, s.service) password, err := utils.RandomPassword() err = s.unit.SetPassword(password) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAs(c, s.unit.Tag(), password) s.uniter = s.st.Uniter() c.Assert(s.uniter, gc.NotNil) // Note: The unit must always have a charm URL set, because this // happens as part of the installation process (that happens // before the initial install hook). err = s.unit.SetCharmURL(sch.URL()) c.Assert(err, gc.IsNil) s.relch = s.AddTestingCharm(c, "mysql") s.relunits = map[int]*state.RelationUnit{} s.relctxs = map[int]*uniter.ContextRelation{} s.AddContextRelation(c, "db0") s.AddContextRelation(c, "db1") }
func (s *serverSuite) TestUnitLoginStartsPinger(c *gc.C) { // Create a new service and unit to verify "agent alive" behavior. service := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress")) unit, err := service.AddUnit() c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = unit.SetPassword(password) c.Assert(err, gc.IsNil) // Not alive yet. s.assertAlive(c, unit, false) // Login as the unit agent of the created unit. st := s.OpenAPIAs(c, unit.Tag(), password) // Make sure the pinger has started. s.assertAlive(c, unit, true) // Now make sure it stops when connection is closed. c.Assert(st.Close(), gc.IsNil) // Sync, then wait for a bit to make sure the state is updated. s.State.StartSync() <-time.After(coretesting.ShortWait) s.State.StartSync() s.assertAlive(c, unit, false) }
func (passwordSuite) TestRandomPassword(c *gc.C) { p, err := utils.RandomPassword() c.Assert(err, gc.IsNil) if len(p) < 18 { c.Errorf("password too short: %q", p) } c.Assert(p, gc.Matches, base64Chars) }
func (s *authHttpSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) user, err := s.State.AddUser("joe", password) c.Assert(err, gc.IsNil) s.userTag = user.Tag() s.password = password }
func (s *FilterSuite) APILogin(c *gc.C, unit *state.Unit) { password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = unit.SetPassword(password) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAs(c, unit.Tag(), password) s.uniter = s.st.Uniter() c.Assert(s.uniter, gc.NotNil) }
func (s *unitSuite) SetUpTest(c *gc.C) { var err error s.JujuConnSuite.SetUpTest(c) svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress")) s.unit, err = svc.AddUnit() c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = s.unit.SetPassword(password) s.st = s.OpenAPIAs(c, s.unit.Tag(), password) }
func (s *serverSuite) TestOpenAsMachineErrors(c *gc.C) { assertNotProvisioned := func(err error) { c.Assert(err, gc.NotNil) c.Assert(err, jc.Satisfies, params.IsCodeNotProvisioned) c.Assert(err, gc.ErrorMatches, `machine \d+ is not provisioned`) } stm, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = stm.SetProvisioned("foo", "fake_nonce", nil) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = stm.SetPassword(password) c.Assert(err, gc.IsNil) // This does almost exactly the same as OpenAPIAsMachine but checks // for failures instead. _, info, err := s.APIConn.Environ.StateInfo() info.Tag = stm.Tag() info.Password = password info.Nonce = "invalid-nonce" st, err := api.Open(info, fastDialOpts) assertNotProvisioned(err) c.Assert(st, gc.IsNil) // Try with empty nonce as well. info.Nonce = "" st, err = api.Open(info, fastDialOpts) assertNotProvisioned(err) c.Assert(st, gc.IsNil) // Finally, with the correct one succeeds. info.Nonce = "fake_nonce" st, err = api.Open(info, fastDialOpts) c.Assert(err, gc.IsNil) c.Assert(st, gc.NotNil) st.Close() // Now add another machine, intentionally unprovisioned. stm1, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = stm1.SetPassword(password) c.Assert(err, gc.IsNil) // Try connecting, it will fail. info.Tag = stm1.Tag() info.Nonce = "" st, err = api.Open(info, fastDialOpts) assertNotProvisioned(err) c.Assert(st, gc.IsNil) }
func (s *unitUpgraderSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) s.rawMachine, _, _, s.rawUnit = s.addMachineServiceCharmAndUnit(c, "wordpress") password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = s.rawUnit.SetPassword(password) c.Assert(err, gc.IsNil) s.stateAPI = s.OpenAPIAs(c, s.rawUnit.Tag(), password) // Create the upgrader facade. s.st = s.stateAPI.Upgrader() c.Assert(s.st, gc.NotNil) }
// OpenAPIAsNewMachine creates a new machine entry that lives in system state, // and then uses that to open the API. The returned *api.State should not be // closed by the caller as a cleanup function has been registered to do that. // The machine will run the supplied jobs; if none are given, JobHostUnits is assumed. func (s *JujuConnSuite) OpenAPIAsNewMachine(c *gc.C, jobs ...state.MachineJob) (*api.State, *state.Machine) { if len(jobs) == 0 { jobs = []state.MachineJob{state.JobHostUnits} } machine, err := s.State.AddMachine("quantal", jobs...) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("foo", "fake_nonce", nil) c.Assert(err, gc.IsNil) return s.openAPIAs(c, machine.Tag(), password, "fake_nonce"), machine }
func (s *serverSuite) TestStop(c *gc.C) { // Start our own instance of the server so we have // a handle on it to stop it. srv, err := apiserver.NewServer( s.State, "localhost:0", []byte(coretesting.ServerCert), []byte(coretesting.ServerKey), "", "") c.Assert(err, gc.IsNil) defer srv.Stop() stm, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = stm.SetProvisioned("foo", "fake_nonce", nil) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = stm.SetPassword(password) c.Assert(err, gc.IsNil) // Note we can't use openAs because we're not connecting to // s.APIConn. apiInfo := &api.Info{ Tag: stm.Tag(), Password: password, Nonce: "fake_nonce", Addrs: []string{srv.Addr()}, CACert: coretesting.CACert, } st, err := api.Open(apiInfo, fastDialOpts) c.Assert(err, gc.IsNil) defer st.Close() _, err = st.Machiner().Machine(stm.Tag()) c.Assert(err, gc.IsNil) err = srv.Stop() c.Assert(err, gc.IsNil) _, err = st.Machiner().Machine(stm.Tag()) // The client has not necessarily seen the server shutdown yet, // so there are two possible errors. if err != rpc.ErrShutdown && err != io.ErrUnexpectedEOF { c.Fatalf("unexpected error from request: %v", err) } // Check it can be stopped twice. err = srv.Stop() c.Assert(err, gc.IsNil) }
func (s *RevisionUpdateSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) s.CharmSuite.SetUpTest(c) machine, err := s.State.AddMachine("quantal", state.JobManageEnviron) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("i-manager", "fake_nonce", nil) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce") c.Assert(s.st, gc.NotNil) }
func (s *loginSuite) setupMachineAndServer(c *gc.C) (*api.Info, func()) { machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("foo", "fake_nonce", nil) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) info, cleanup := s.setupServer(c) info.Tag = machine.Tag() info.Password = password info.Nonce = "fake_nonce" return info, cleanup }
func (auth *simpleAuth) SetupAuthentication(machine TaggedPasswordChanger) (*state.Info, *api.Info, error) { password, err := utils.RandomPassword() if err != nil { return nil, nil, fmt.Errorf("cannot make password for machine %v: %v", machine, err) } if err := machine.SetPassword(password); err != nil { return nil, nil, fmt.Errorf("cannot set API password for machine %v: %v", machine, err) } stateInfo := *auth.stateInfo stateInfo.Tag = machine.Tag() stateInfo.Password = password apiInfo := *auth.apiInfo apiInfo.Tag = machine.Tag() apiInfo.Password = password return &stateInfo, &apiInfo, nil }
func (passwordSuite) TestAgentPasswordHash(c *gc.C) { seenValues := make(map[string]bool) for i := 0; i < 1000; i++ { password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) c.Assert(seenValues[password], jc.IsFalse) seenValues[password] = true hashed := utils.AgentPasswordHash(password) c.Assert(hashed, gc.Not(gc.Equals), password) c.Assert(seenValues[hashed], jc.IsFalse) seenValues[hashed] = true c.Assert(len(hashed), gc.Equals, 24) // check we're not adding base64 padding. c.Assert(hashed, gc.Matches, base64Chars) } }
func (s *CommonProvisionerSuite) APILogin(c *gc.C, machine *state.Machine) { if s.st != nil { c.Assert(s.st.Close(), gc.IsNil) } password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("i-fake", "fake_nonce", nil) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce") c.Assert(s.st, gc.NotNil) c.Logf("API: login as %q successful", machine.Tag()) s.provisioner = s.st.Provisioner() c.Assert(s.provisioner, gc.NotNil) }
func (s *JujuConnSuite) AgentConfigForTag(c *gc.C, tag string) agent.Config { password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) config, err := agent.NewAgentConfig( agent.AgentConfigParams{ DataDir: s.DataDir(), Tag: tag, UpgradedToVersion: version.Current.Number, Password: password, Nonce: "nonce", StateAddresses: s.StateInfo(c).Addrs, APIAddresses: s.APIInfo(c).Addrs, CACert: testing.CACert, }) c.Assert(err, gc.IsNil) return config }
// initBootstrapMachine initializes the initial bootstrap machine in state. func initBootstrapMachine(c ConfigSetter, st *state.State, cfg BootstrapMachineConfig) (*state.Machine, error) { logger.Infof("initialising bootstrap machine with config: %+v", cfg) jobs := make([]state.MachineJob, len(cfg.Jobs)) for i, job := range cfg.Jobs { machineJob, err := state.MachineJobFromParams(job) if err != nil { return nil, fmt.Errorf("invalid bootstrap machine job %q: %v", job, err) } jobs[i] = machineJob } m, err := st.AddOneMachine(state.MachineTemplate{ Addresses: cfg.Addresses, Series: version.Current.Series, Nonce: state.BootstrapNonce, Constraints: cfg.Constraints, InstanceId: cfg.InstanceId, HardwareCharacteristics: cfg.Characteristics, Jobs: jobs, }) if err != nil { return nil, fmt.Errorf("cannot create bootstrap machine in state: %v", err) } if m.Id() != BootstrapMachineId { return nil, fmt.Errorf("bootstrap machine expected id 0, got %q", m.Id()) } // Read the machine agent's password and change it to // a new password (other agents will change their password // via the API connection). logger.Debugf("create new random password for machine %v", m.Id()) newPassword, err := utils.RandomPassword() if err != nil { return nil, err } if err := m.SetPassword(newPassword); err != nil { return nil, err } if err := m.SetMongoPassword(newPassword); err != nil { return nil, err } c.SetPassword(newPassword) return m, nil }
// deploy will deploy the supplied unit with the deployer's manager. It will // panic if it observes inconsistent internal state. func (d *Deployer) deploy(unit *apideployer.Unit) error { unitName := unit.Name() if d.deployed.Contains(unit.Name()) { panic("must not re-deploy a deployed unit") } logger.Infof("deploying unit %q", unitName) initialPassword, err := utils.RandomPassword() if err != nil { return err } if err := unit.SetPassword(initialPassword); err != nil { return fmt.Errorf("cannot set password for unit %q: %v", unitName, err) } if err := d.ctx.DeployUnit(unitName, initialPassword); err != nil { return err } d.deployed.Add(unitName) return nil }
func (s *BundlesDirSuite) SetUpTest(c *gc.C) { s.HTTPSuite.SetUpTest(c) s.JujuConnSuite.SetUpTest(c) // Add a charm, service and unit to login to the API with. charm := s.AddTestingCharm(c, "wordpress") service := s.AddTestingService(c, "wordpress", charm) unit, err := service.AddUnit() c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = unit.SetPassword(password) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAs(c, unit.Tag(), password) c.Assert(s.st, gc.NotNil) s.uniter = s.st.Uniter() c.Assert(s.uniter, gc.NotNil) }
func (s *FirewallerSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) s.charm = s.AddTestingCharm(c, "dummy") // Create a manager machine and login to the API. machine, err := s.State.AddMachine("quantal", state.JobManageEnviron) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("i-manager", "fake_nonce", nil) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce") c.Assert(s.st, gc.NotNil) // Create the firewaller API facade. s.firewaller = s.st.Firewaller() c.Assert(s.firewaller, gc.NotNil) }
func (s *uniterSuite) setUpTest(c *gc.C, addStateServer bool) { s.JujuConnSuite.SetUpTest(c) if addStateServer { s.stateServerMachine = testing.AddStateServerMachine(c, s.State) } // Create a machine, a service and add a unit so we can log in as // its agent. s.wordpressMachine, s.wordpressService, s.wordpressCharm, s.wordpressUnit = s.addMachineServiceCharmAndUnit(c, "wordpress") password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = s.wordpressUnit.SetPassword(password) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAs(c, s.wordpressUnit.Tag(), password) // Create the uniter API facade. s.uniter = s.st.Uniter() c.Assert(s.uniter, gc.NotNil) }
func (s *toolsSuite) TestAuthRequiresUser(c *gc.C) { // Add a machine and try to login. machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("foo", "fake_nonce", nil) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) resp, err := s.sendRequest(c, machine.Tag(), password, "POST", s.toolsURI(c, ""), "", nil) c.Assert(err, gc.IsNil) s.assertErrorResponse(c, resp, http.StatusUnauthorized, "unauthorized") // Now try a user login. resp, err = s.authRequest(c, "POST", s.toolsURI(c, ""), "", nil) c.Assert(err, gc.IsNil) s.assertErrorResponse(c, resp, http.StatusBadRequest, "expected binaryVersion argument") }
func (s *firewallerSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) // Reset previous machines and units (if any) and create 3 // machines for the tests. The first one is a manager node. s.machines = make([]*state.Machine, 3) s.units = make([]*state.Unit, 3) var err error s.machines[0], err = s.State.AddMachine("quantal", state.JobManageEnviron, state.JobHostUnits) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = s.machines[0].SetPassword(password) c.Assert(err, gc.IsNil) err = s.machines[0].SetProvisioned("i-manager", "fake_nonce", nil) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAsMachine(c, s.machines[0].Tag(), password, "fake_nonce") c.Assert(s.st, gc.NotNil) // Note that the specific machine ids allocated are assumed // to be numerically consecutive from zero. for i := 1; i <= 2; i++ { s.machines[i], err = s.State.AddMachine("quantal", state.JobHostUnits) c.Check(err, gc.IsNil) } // Create a service and three units for these machines. s.charm = s.AddTestingCharm(c, "wordpress") s.service = s.AddTestingService(c, "wordpress", s.charm) // Add the rest of the units and assign them. for i := 0; i <= 2; i++ { s.units[i], err = s.service.AddUnit() c.Check(err, gc.IsNil) err = s.units[i].AssignToMachine(s.machines[i]) c.Check(err, gc.IsNil) } // Create the firewaller API facade. s.firewaller = s.st.Firewaller() c.Assert(s.firewaller, gc.NotNil) }
func (s *loginSuite) TestLoginSetsLogIdentifier(c *gc.C) { info, cleanup := s.setupServer(c) defer cleanup() machineInState, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = machineInState.SetProvisioned("foo", "fake_nonce", nil) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machineInState.SetPassword(password) c.Assert(err, gc.IsNil) c.Assert(machineInState.Tag(), gc.Equals, "machine-0") tw := &loggo.TestWriter{} c.Assert(loggo.RegisterWriter("login-tester", tw, loggo.DEBUG), gc.IsNil) defer loggo.RemoveWriter("login-tester") info.Tag = machineInState.Tag() info.Password = password info.Nonce = "fake_nonce" apiConn, err := api.Open(info, fastDialOpts) c.Assert(err, gc.IsNil) apiMachine, err := apiConn.Machiner().Machine(machineInState.Tag()) c.Assert(err, gc.IsNil) c.Assert(apiMachine.Tag(), gc.Equals, machineInState.Tag()) apiConn.Close() c.Assert(tw.Log, jc.LogMatches, []string{ `<- \[[0-9A-F]+\] <unknown> {"RequestId":1,"Type":"Admin","Request":"Login","Params":` + `{"AuthTag":"machine-0","Password":"******"]*","Nonce":"fake_nonce"}` + `}`, // Now that we are logged in, we see the entity's tag // [0-9.umns] is to handle timestamps that are ns, us, ms, or s // long, though we expect it to be in the 'ms' range. `-> \[[0-9A-F]+\] machine-0 [0-9.]+[umn]?s {"RequestId":1,"Response":{"Servers":\[\]}} Admin\[""\].Login`, `<- \[[0-9A-F]+\] machine-0 {"RequestId":2,"Type":"Machiner","Request":"Life","Params":{"Entities":\[{"Tag":"machine-0"}\]}}`, `-> \[[0-9A-F]+\] machine-0 [0-9.umns]+ {"RequestId":2,"Response":{"Results":\[{"Life":"alive","Error":null}\]}} Machiner\[""\]\.Life`, }) }
func (s *provisionerSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) var err error s.machine, err = s.State.AddMachine("quantal", state.JobManageEnviron) c.Assert(err, gc.IsNil) password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = s.machine.SetPassword(password) c.Assert(err, gc.IsNil) err = s.machine.SetInstanceInfo("i-manager", "fake_nonce", nil, nil, nil) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAsMachine(c, s.machine.Tag(), password, "fake_nonce") c.Assert(s.st, gc.NotNil) err = s.machine.SetAddresses(instance.NewAddress("0.1.2.3", instance.NetworkUnknown)) c.Assert(err, gc.IsNil) // Create the provisioner API facade. s.provisioner = s.st.Provisioner() c.Assert(s.provisioner, gc.NotNil) s.EnvironWatcherTests = apitesting.NewEnvironWatcherTests(s.provisioner, s.BackingState, apitesting.HasSecrets) s.APIAddresserTests = apitesting.NewAPIAddresserTests(s.provisioner, s.BackingState) }
// openAPIState opens the API using the given information, and // returns the opened state and the api entity with // the given tag. The given changeConfig function is // called if the password changes to set the password. func openAPIState( agentConfig agent.Config, a Agent, ) (_ *api.State, _ *apiagent.Entity, err error) { // We let the API dial fail immediately because the // runner's loop outside the caller of openAPIState will // keep on retrying. If we block for ages here, // then the worker that's calling this cannot // be interrupted. info := agentConfig.APIInfo() st, err := apiOpen(info, api.DialOpts{}) usedOldPassword := false if params.IsCodeUnauthorized(err) { // We've perhaps used the wrong password, so // try again with the fallback password. info := *info info.Password = agentConfig.OldPassword() usedOldPassword = true st, err = apiOpen(&info, api.DialOpts{}) } if err != nil { if params.IsCodeNotProvisioned(err) { return nil, nil, worker.ErrTerminateAgent } if params.IsCodeUnauthorized(err) { return nil, nil, worker.ErrTerminateAgent } return nil, nil, err } defer func() { if err != nil { st.Close() } }() entity, err := st.Agent().Entity(a.Tag()) if err == nil && entity.Life() == params.Dead { return nil, nil, worker.ErrTerminateAgent } if err != nil { if params.IsCodeUnauthorized(err) { return nil, nil, worker.ErrTerminateAgent } return nil, nil, err } if usedOldPassword { // We succeeded in connecting with the fallback // password, so we need to create a new password // for the future. newPassword, err := utils.RandomPassword() if err != nil { return nil, nil, err } // Change the configuration *before* setting the entity // password, so that we avoid the possibility that // we might successfully change the entity's // password but fail to write the configuration, // thus locking us out completely. if err := a.ChangeConfig(func(c agent.ConfigSetter) { c.SetPassword(newPassword) c.SetOldPassword(info.Password) }); err != nil { return nil, nil, err } if err := entity.SetPassword(newPassword); err != nil { return nil, nil, err } } return st, entity, nil }