// newState returns a new State that uses the given environment. // The environment must have already been bootstrapped. func newState(environ environs.Environ, mongoInfo *mongo.MongoInfo) (*state.State, error) { password := environ.Config().AdminSecret() if password == "" { return nil, fmt.Errorf("cannot connect without admin-secret") } if err := environs.CheckEnvironment(environ); err != nil { return nil, err } mongoInfo.Password = password opts := mongo.DefaultDialOpts() st, err := state.Open(mongoInfo, opts, environs.NewStatePolicy()) if errors.IsUnauthorized(err) { // We try for a while because we might succeed in // connecting to mongo before the state has been // initialized and the initial password set. for a := redialStrategy.Start(); a.Next(); { st, err = state.Open(mongoInfo, opts, environs.NewStatePolicy()) if !errors.IsUnauthorized(err) { break } } if err != nil { return nil, err } } else if err != nil { return nil, err } if err := updateSecrets(environ, st); err != nil { st.Close() return nil, fmt.Errorf("unable to push secrets: %v", err) } return st, nil }
// NewConn returns a new Conn that uses the // given environment. The environment must have already // been bootstrapped. func NewConn(environ environs.Environ) (*Conn, error) { info, _, err := environ.StateInfo() if err != nil { return nil, err } password := environ.Config().AdminSecret() if password == "" { return nil, fmt.Errorf("cannot connect without admin-secret") } err = environs.CheckEnvironment(environ) if err != nil { return nil, err } info.Password = password opts := mongo.DefaultDialOpts() st, err := state.Open(info, opts, environs.NewStatePolicy()) if errors.IsUnauthorized(err) { logger.Infof("authorization error while connecting to state server; retrying") // We can't connect with the administrator password,; // perhaps this was the first connection and the // password has not been changed yet. info.Password = utils.UserPasswordHash(password, utils.CompatSalt) // We try for a while because we might succeed in // connecting to mongo before the state has been // initialized and the initial password set. for a := redialStrategy.Start(); a.Next(); { st, err = state.Open(info, opts, environs.NewStatePolicy()) if !errors.IsUnauthorized(err) { break } } if err != nil { return nil, err } if err := st.SetAdminMongoPassword(password); err != nil { return nil, err } } else if err != nil { return nil, err } conn := &Conn{ Environ: environ, State: st, } if err := conn.updateSecrets(); err != nil { conn.Close() return nil, fmt.Errorf("unable to push secrets: %v", err) } return conn, nil }
func (s *checkEnvironmentSuite) TestCheckEnvironment(c *gc.C) { ctx := testing.Context(c) environ, err := environs.PrepareFromName("test", ctx, configstore.NewMem()) c.Assert(err, gc.IsNil) // VerifyStorage is sufficient for our tests and much simpler // than Bootstrap which calls it. stor := environ.Storage() err = environs.VerifyStorage(stor) c.Assert(err, gc.IsNil) err = environs.CheckEnvironment(environ) c.Assert(err, gc.IsNil) }
func (s *checkEnvironmentSuite) TestCheckEnvironmentBadContent(c *gc.C) { ctx := testing.Context(c) environ, err := environs.PrepareFromName("test", ctx, configstore.NewMem()) c.Assert(err, gc.IsNil) // We mock a bad (eg. from a Python-juju environment) bootstrap-verify. stor := environ.Storage() content := "bad verification content" reader := strings.NewReader(content) err = stor.Put(environs.VerificationFilename, reader, int64(len(content))) c.Assert(err, gc.IsNil) // When the bootstrap-verify file contains unexpected content, // we get an InvalidEnvironmentError. err = environs.CheckEnvironment(environ) c.Assert(err, gc.Equals, environs.InvalidEnvironmentError) }
func (s *checkEnvironmentSuite) TestCheckEnvironmentGetFails(c *gc.C) { ctx := testing.Context(c) environ, err := environs.PrepareFromName("test", ctx, configstore.NewMem()) c.Assert(err, gc.IsNil) // VerifyStorage is sufficient for our tests and much simpler // than Bootstrap which calls it. stor := environ.Storage() err = environs.VerifyStorage(stor) c.Assert(err, gc.IsNil) // When fetching the verification file from storage fails, // we get an InvalidEnvironmentError. someError := errors.Unauthorizedf("you shall not pass") dummy.Poison(stor, environs.VerificationFilename, someError) err = environs.CheckEnvironment(environ) c.Assert(err, gc.Equals, someError) }
func (s *checkEnvironmentSuite) TestCheckEnvironmentFileNotFound(c *gc.C) { ctx := testing.Context(c) environ, err := environs.PrepareFromName("test", ctx, configstore.NewMem()) c.Assert(err, gc.IsNil) // VerifyStorage is sufficient for our tests and much simpler // than Bootstrap which calls it. stor := environ.Storage() err = environs.VerifyStorage(stor) c.Assert(err, gc.IsNil) // When the bootstrap-verify file does not exist, it still believes // the environment is a juju-core one because earlier versions // did not create that file. err = stor.Remove(environs.VerificationFilename) c.Assert(err, gc.IsNil) err = environs.CheckEnvironment(environ) c.Assert(err, gc.IsNil) }
// newState returns a new State that uses the given environment. // The environment must have already been bootstrapped. func newState(environ environs.Environ, mongoInfo *authentication.MongoInfo) (*state.State, error) { password := environ.Config().AdminSecret() if password == "" { return nil, fmt.Errorf("cannot connect without admin-secret") } if err := environs.CheckEnvironment(environ); err != nil { return nil, err } mongoInfo.Password = password opts := mongo.DefaultDialOpts() st, err := state.Open(mongoInfo, opts, environs.NewStatePolicy()) if errors.IsUnauthorized(err) { // We can't connect with the administrator password,; // perhaps this was the first connection and the // password has not been changed yet. mongoInfo.Password = utils.UserPasswordHash(password, utils.CompatSalt) // We try for a while because we might succeed in // connecting to mongo before the state has been // initialized and the initial password set. for a := redialStrategy.Start(); a.Next(); { st, err = state.Open(mongoInfo, opts, environs.NewStatePolicy()) if !errors.IsUnauthorized(err) { break } } if err != nil { return nil, err } if err := st.SetAdminMongoPassword(password); err != nil { return nil, err } } else if err != nil { return nil, err } if err := updateSecrets(environ, st); err != nil { st.Close() return nil, fmt.Errorf("unable to push secrets: %v", err) } return st, nil }