// addAPIInfo adds information to the agent's configuration // for serving the API. func addAPIInfo(conf *agent.Conf, m *state.Machine) { port := testing.FindTCPPort() conf.APIInfo.Addrs = []string{fmt.Sprintf("localhost:%d", port)} conf.APIInfo.CACert = []byte(testing.CACert) conf.StateServerCert = []byte(testing.ServerCert) conf.StateServerKey = []byte(testing.ServerKey) conf.APIPort = port }
func (s *openSuite) TestOpenStateNormal(c *C) { conf := agent.Conf{ StateInfo: s.StateInfo(c), } conf.OldPassword = "******" st, err := conf.OpenState() c.Assert(err, IsNil) st.Close() }
func (suite) TestCheckNoDataDir(c *C) { conf := agent.Conf{ StateInfo: &state.Info{ Addrs: []string{"x:4"}, CACert: []byte("xxx"), Tag: "bar", Password: "******", }, } c.Assert(conf.Check(), ErrorMatches, "data directory not found in configuration") }
// EnsureAPIInfo makes sure we can connect as an agent to the API server 1.10 // did not set an API password for machine agents, 1.11 sets it the same as the // mongo password. 1.10 also does not set any API Info at all for Unit agents. // conf is the agent.conf for this machine/unit agent. agentConn is the direct // connection to the State database func EnsureAPIInfo(conf *agent.Conf, stConn *state.State, agentConn AgentState) error { // In 1.10 Machine Agents will have an API Info section, but will not // have properly configured the Password field, so when upgrading to // 1.11 we must set that field // In 1.10 Unit Agents will not have an API Info section at all, so we // must set everything from the StateInfo (correcting the Addrs for API // port vs Mongo port) // A new 1.11 Unit Agent will have an OldPassword but no Password set // (in StateInfo or APIInfo). Because we only change the password on // API connect, not on DB connect. We don't want to make extra // SetPassword calls when we already have a valid password set if conf.APIInfo != nil && (conf.APIInfo.Password != "" || conf.StateInfo.Password == "") { // We must have set it earlier return nil } setter, ok := agentConn.(passwordSetter) if !ok { panic("AgentState is missing a SetPassword method?") } if conf.APIInfo == nil { // Unit agents didn't get any APIInfo in 1.10 conf.APIInfo = apiInfoFromStateInfo(conf.StateInfo, stConn) validationLogger.Infof( "agent.conf APIInfo is not set. Setting to {Addrs: %s, Tag: %s}", conf.APIInfo.Addrs, conf.APIInfo.Tag, ) } else { validationLogger.Infof("agent.conf APIInfo password is not set. Setting to state password") conf.APIInfo.Password = conf.StateInfo.Password } password := conf.StateInfo.Password if password == "" { // In 1.11 we don't set a new password on connect (because it is // done in the API code, and we don't have any API workers). // We want to make sure the API user has the correct password // (OldPassword). We *don't* want to set APIInfo.Password // because then when we do connect via the API we wouldn't // change the password. So this is only used for SetPassword validationLogger.Infof( "agent.conf StateInfo password is \"\". Setting Agent password for %s to OldPassword", conf.APIInfo.Tag) password = conf.OldPassword } // We set the actual password before writing it to disk, because // otherwise we would not set it correctly in the future if err := setter.SetPassword(password); err != nil { return err } if err := conf.Write(); err != nil { return err } return nil }
func (s *openSuite) TestOpenAPINormal(c *C) { conf := agent.Conf{ APIInfo: s.APIInfo(c), } conf.OldPassword = "******" st, newPassword, err := conf.OpenAPI(api.DialOpts{}) c.Assert(err, IsNil) defer st.Close() c.Assert(newPassword, Equals, "") c.Assert(st, NotNil) }
func (s *openSuite) TestOpenStateNoPassword(c *C) { conf := agent.Conf{ StateInfo: s.StateInfo(c), } conf.OldPassword = conf.StateInfo.Password conf.StateInfo.Password = "" st, err := conf.OpenState() c.Assert(err, IsNil) c.Assert(st, NotNil) st.Close() }
func (suite) TestConfFile(c *C) { conf := agent.Conf{ DataDir: "/foo", StateInfo: &state.Info{ Addrs: []string{"x:4"}, CACert: []byte("xxx"), Tag: "bar", Password: "******", }, } c.Assert(conf.File("x/y"), Equals, "/foo/agents/bar/x/y") }
func (s *openSuite) TestOpenStateFallbackPassword(c *gc.C) { conf := agent.Conf{ StateInfo: s.StateInfo(c), } conf.OldPassword = conf.StateInfo.Password conf.StateInfo.Password = "******" st, err := conf.OpenState() c.Assert(err, gc.IsNil) c.Assert(st, gc.NotNil) st.Close() }
func openState(c *agent.Conf, a Agent) (*state.State, AgentState, error) { st, err := c.OpenState() if err != nil { return nil, nil, err } entity, err := a.Entity(st) if errors.IsNotFoundError(err) || err == nil && entity.Life() == state.Dead { err = worker.ErrTerminateAgent } if err != nil { st.Close() return nil, nil, err } return st, entity, nil }
func (s *openSuite) TestOpenAPINoPassword(c *C) { conf := agent.Conf{ APIInfo: s.APIInfo(c), } conf.OldPassword = conf.APIInfo.Password conf.APIInfo.Password = "" st, newPassword, err := conf.OpenAPI(api.DialOpts{}) c.Assert(err, IsNil) defer st.Close() c.Assert(newPassword, Matches, ".+") c.Assert(st, NotNil) p, err := utils.RandomPassword() c.Assert(err, IsNil) c.Assert(newPassword, HasLen, len(p)) c.Assert(conf.OldPassword, Equals, s.APIInfo(c).Password) }
func (s *openSuite) TestOpenAPIFallbackPassword(c *gc.C) { conf := agent.Conf{ APIInfo: s.APIInfo(c), } conf.OldPassword = conf.APIInfo.Password conf.APIInfo.Password = "******" st, newPassword, err := conf.OpenAPI(api.DialOpts{}) c.Assert(err, gc.IsNil) defer st.Close() c.Assert(newPassword, gc.Matches, ".+") c.Assert(st, gc.NotNil) p, err := utils.RandomPassword() c.Assert(err, gc.IsNil) c.Assert(newPassword, gc.HasLen, len(p)) c.Assert(conf.OldPassword, gc.Equals, s.APIInfo(c).Password) }
func openAPIState(c *agent.Conf, a Agent) (*api.State, AgentAPIState, 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. st, newPassword, err := c.OpenAPI(api.DialOpts{}) if err != nil { return nil, nil, err } entity, err := a.APIEntity(st) if params.ErrCode(err) == params.CodeNotFound || err == nil && entity.Life() == params.Dead { err = worker.ErrTerminateAgent } if err != nil { st.Close() return nil, nil, err } if newPassword == "" { return st, entity, nil } // Make a copy of the configuration so that if we fail // to write the configuration file, the configuration will // still be valid. c1 := *c stateInfo := *c.StateInfo c1.StateInfo = &stateInfo apiInfo := *c.APIInfo c1.APIInfo = &apiInfo c1.StateInfo.Password = newPassword c1.APIInfo.Password = newPassword if err := c1.Write(); err != nil { return nil, nil, err } *c = c1 if err := entity.SetPassword(newPassword); err != nil { return nil, nil, err } return st, entity, nil }