func generateUserJenv(envName, user, password, outPath string) error { store, err := configstore.Default() if err != nil { return errors.Trace(err) } storeInfo, err := store.ReadInfo(envName) if err != nil { return errors.Trace(err) } endpoint := storeInfo.APIEndpoint() outputInfo := configstore.EnvironInfoData{ User: user, Password: password, EnvironUUID: endpoint.EnvironUUID, StateServers: endpoint.Addresses, CACert: endpoint.CACert, } yaml, err := cmd.FormatYaml(outputInfo) if err != nil { return errors.Trace(err) } outFile, err := os.Create(outPath) if err != nil { return errors.Trace(err) } defer outFile.Close() outFile.Write(yaml) if err != nil { return errors.Trace(err) } return nil }
func GenerateUserJenv(envName, user, password, outPath string) error { store, err := configstore.Default() if err != nil { return errors.Trace(err) } storeInfo, err := store.ReadInfo(envName) if err != nil { return errors.Trace(err) } outputInfo := configstore.EnvironInfoData{} outputInfo.User = user outputInfo.Password = password outputInfo.StateServers = storeInfo.APIEndpoint().Addresses outputInfo.CACert = storeInfo.APIEndpoint().CACert yaml, err := cmd.FormatYaml(outputInfo) if err != nil { return errors.Trace(err) } outFile, err := os.Create(outPath) if err != nil { return errors.Trace(err) } defer outFile.Close() outFile.Write(yaml) if err != nil { return errors.Trace(err) } return nil }
func (c *UserInfoCommand) Run(ctx *cmd.Context) (err error) { client, err := getUserInfoAPI(c) if err != nil { return err } defer client.Close() username := c.Username if username == "" { // No username given, get current user store, err := configstore.Default() if err != nil { return err } info, err := store.ReadInfo(c.EnvName) if err != nil { return err } username = info.APICredentials().User } userTag := names.NewUserTag(username) result, err := client.UserInfo(userTag.Id()) if err != nil { return err } info := UserInfo{ Username: result.Result.Username, DisplayName: result.Result.DisplayName, DateCreated: result.Result.DateCreated.String(), LastConnection: result.Result.LastConnection.String(), } if err = c.out.Write(ctx, info); err != nil { return err } return nil }
// APIEndpointForEnv returns the endpoint information for a given environment // It tries to just return the information from the cached settings unless // there is nothing cached or refresh is True func APIEndpointForEnv(envName string, refresh bool) (configstore.APIEndpoint, error) { store, err := configstore.Default() if err != nil { return configstore.APIEndpoint{}, err } return apiEndpointInStore(envName, refresh, store, defaultAPIOpen) }
func (s *cmdControllerSuite) TestSystemKillCallsEnvironDestroyOnHostedEnviron(c *gc.C) { st := s.Factory.MakeEnvironment(c, &factory.EnvParams{ Name: "foo", }) defer st.Close() st.SwitchBlockOn(state.DestroyBlock, "TestBlockDestroyEnvironment") st.Close() opc := make(chan dummy.Operation, 200) dummy.Listen(opc) conn, err := juju.NewAPIState(s.AdminUserTag(c), s.Environ, api.DialOpts{}) c.Assert(err, jc.ErrorIsNil) s.AddCleanup(func(*gc.C) { conn.Close() }) client := undertakerapi.NewClient(conn) startTime := time.Date(2015, time.September, 1, 17, 2, 1, 0, time.UTC) mClock := testing.NewClock(startTime) undertaker.NewUndertaker(client, mClock) store, err := configstore.Default() _, err = store.ReadInfo("dummyenv") c.Assert(err, jc.ErrorIsNil) s.run(c, "kill-controller", "dummyenv", "-y") // Ensure that Destroy was called on the hosted environment ... opRecvTimeout(c, st, opc, dummy.OpDestroy{}) // ... and that the configstore was removed. _, err = store.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (c *DestroyEnvironmentCommand) Run(ctx *cmd.Context) (result error) { store, err := configstore.Default() if err != nil { return fmt.Errorf("cannot open environment info storage: %v", err) } environ, err := environs.NewFromName(c.envName, store) if err != nil { if environs.IsEmptyConfig(err) { // Delete the .jenv file and call it done. ctx.Infof("removing empty environment file") return environs.DestroyInfo(c.envName, store) } return err } if !c.assumeYes { fmt.Fprintf(ctx.Stdout, destroyEnvMsg, environ.Name(), environ.Config().Type()) scanner := bufio.NewScanner(ctx.Stdin) scanner.Scan() err := scanner.Err() if err != nil && err != io.EOF { return fmt.Errorf("Environment destruction aborted: %s", err) } answer := strings.ToLower(scanner.Text()) if answer != "y" && answer != "yes" { return errors.New("environment destruction aborted") } } // If --force is supplied, then don't attempt to use the API. // This is necessary to destroy broken environments, where the // API server is inaccessible or faulty. if !c.force { defer func() { if result == nil { return } logger.Errorf(`failed to destroy environment %q If the environment is unusable, then you may run juju destroy-environment --force to forcefully destroy the environment. Upon doing so, review your environment provider console for any resources that need to be cleaned up. `, c.envName) }() apiclient, err := juju.NewAPIClientFromName(c.envName) if err != nil { return fmt.Errorf("cannot connect to API: %v", err) } defer apiclient.Close() err = apiclient.DestroyEnvironment() if err != nil && !params.IsCodeNotImplemented(err) { return fmt.Errorf("destroying environment: %v", err) } } return environs.Destroy(environ, store) }
// environFromName loads an existing environment or prepares a new // one. If there are no errors, it returns the environ and a closure to // clean up in case we need to further up the stack. If an error has // occurred, the environment and cleanup function will be nil, and the // error will be filled in. func environFromName( ctx *cmd.Context, envName string, action string, ) (env environs.Environ, cleanup func(), err error) { store, err := configstore.Default() if err != nil { return nil, nil, err } envExisted := false if environInfo, err := store.ReadInfo(envName); err == nil { envExisted = true logger.Warningf( "ignoring environments.yaml: using bootstrap config in %s", environInfo.Location(), ) } else if !errors.IsNotFound(err) { return nil, nil, err } if env, err = environs.PrepareFromName(envName, ctx, store); err != nil { return nil, nil, err } cleanup = func() { if !envExisted { destroyPreparedEnviron(ctx, env, store, action) } } return env, cleanup, nil }
// Run implements Command.Run func (c *destroyCommand) Run(ctx *cmd.Context) error { store, err := configstore.Default() if err != nil { return errors.Annotate(err, "cannot open controller info storage") } cfgInfo, err := store.ReadInfo(c.ModelName()) if err != nil { return errors.Annotate(err, "cannot read controller info") } // Verify that we're destroying a controller apiEndpoint := cfgInfo.APIEndpoint() if apiEndpoint.ServerUUID != "" && apiEndpoint.ModelUUID != apiEndpoint.ServerUUID { return errors.Errorf("%q is not a controller; use juju model destroy to destroy it", c.ModelName()) } if !c.assumeYes { if err = confirmDestruction(ctx, c.ModelName()); err != nil { return err } } // Attempt to connect to the API. If we can't, fail the destroy. Users will // need to use the controller kill command if we can't connect. api, err := c.getControllerAPI() if err != nil { return c.ensureUserFriendlyErrorLog(errors.Annotate(err, "cannot connect to API"), ctx, nil) } defer api.Close() // Obtain bootstrap / controller environ information controllerEnviron, err := c.getControllerEnviron(cfgInfo, api) if err != nil { return errors.Annotate(err, "cannot obtain bootstrap information") } // Attempt to destroy the controller. err = api.DestroyController(c.destroyEnvs) if err != nil { return c.ensureUserFriendlyErrorLog(errors.Annotate(err, "cannot destroy controller"), ctx, api) } ctx.Infof("Destroying controller %q", c.ModelName()) if c.destroyEnvs { ctx.Infof("Waiting for hosted model resources to be reclaimed.") updateStatus := newTimedStatusUpdater(ctx, api, apiEndpoint.ModelUUID) for ctrStatus, envsStatus := updateStatus(0); hasUnDeadEnvirons(envsStatus); ctrStatus, envsStatus = updateStatus(2 * time.Second) { ctx.Infof(fmtCtrStatus(ctrStatus)) for _, envStatus := range envsStatus { ctx.Verbosef(fmtEnvStatus(envStatus)) } } ctx.Infof("All hosted models reclaimed, cleaning up controller machines") } return environs.Destroy(controllerEnviron, store) }
func (c *restoreCommand) Run(ctx *cmd.Context) error { if c.showDescription { fmt.Fprintf(ctx.Stdout, "%s\n", c.Info().Purpose) return nil } if err := c.Log.Start(ctx); err != nil { return err } agentConf, err := extractConfig(c.backupFile) if err != nil { return errors.Annotate(err, "cannot extract configuration from backup file") } progress("extracted credentials from backup file") store, err := configstore.Default() if err != nil { return err } cfg, err := c.Config(store) if err != nil { return err } env, err := rebootstrap(cfg, ctx, c.Constraints) if err != nil { return errors.Annotate(err, "cannot re-bootstrap environment") } progress("connecting to newly bootstrapped instance") var apiState *api.State // The state server backend may not be ready to accept logins so we retry. // We'll do up to 8 retries over 2 minutes to give the server time to come up. // Typically we expect only 1 retry will be needed. attempt := utils.AttemptStrategy{Delay: 15 * time.Second, Min: 8} for a := attempt.Start(); a.Next(); { apiState, err = juju.NewAPIState(env, api.DefaultDialOpts()) if err == nil || errors.Cause(err).Error() != "EOF" { break } progress("bootstrapped instance not ready - attempting to redial") } if err != nil { return errors.Annotate(err, "cannot connect to bootstrap instance") } progress("restoring bootstrap machine") machine0Addr, err := restoreBootstrapMachine(apiState, c.backupFile, agentConf) if err != nil { return errors.Annotate(err, "cannot restore bootstrap machine") } progress("restored bootstrap machine") apiState, err = juju.NewAPIState(env, api.DefaultDialOpts()) progress("opening state") if err != nil { return errors.Annotate(err, "cannot connect to api server") } progress("updating all machines") if err := updateAllMachines(apiState, machine0Addr); err != nil { return errors.Annotate(err, "cannot update machines") } return nil }
func (s *JujuConnSuite) setUpConn(c *gc.C) { if s.RootDir != "" { panic("JujuConnSuite.setUpConn without teardown") } s.RootDir = c.MkDir() s.oldHome = utils.Home() home := filepath.Join(s.RootDir, "/home/ubuntu") err := os.MkdirAll(home, 0777) c.Assert(err, gc.IsNil) utils.SetHome(home) s.oldJujuHome = osenv.SetJujuHome(filepath.Join(home, ".juju")) err = os.Mkdir(osenv.JujuHome(), 0777) c.Assert(err, gc.IsNil) err = os.MkdirAll(s.DataDir(), 0777) c.Assert(err, gc.IsNil) s.PatchEnvironment(osenv.JujuEnvEnvKey, "") // TODO(rog) remove these files and add them only when // the tests specifically need them (in cmd/juju for example) s.writeSampleConfig(c, osenv.JujuHomePath("environments.yaml")) err = ioutil.WriteFile(osenv.JujuHomePath("dummyenv-cert.pem"), []byte(testing.CACert), 0666) c.Assert(err, gc.IsNil) err = ioutil.WriteFile(osenv.JujuHomePath("dummyenv-private-key.pem"), []byte(testing.CAKey), 0600) c.Assert(err, gc.IsNil) store, err := configstore.Default() c.Assert(err, gc.IsNil) s.ConfigStore = store ctx := testing.Context(c) environ, err := environs.PrepareFromName("dummyenv", ctx, s.ConfigStore) c.Assert(err, gc.IsNil) // sanity check we've got the correct environment. c.Assert(environ.Config().Name(), gc.Equals, "dummyenv") s.PatchValue(&dummy.DataDir, s.DataDir()) s.LogDir = c.MkDir() s.PatchValue(&dummy.LogDir, s.LogDir) versions := PreferredDefaultVersions(environ.Config(), version.Binary{Number: version.Current.Number, Series: "precise", Arch: "amd64"}) versions = append(versions, version.Current) // Upload tools for both preferred and fake default series envtesting.MustUploadFakeToolsVersions(environ.Storage(), versions...) err = bootstrap.Bootstrap(ctx, environ, bootstrap.BootstrapParams{}) c.Assert(err, gc.IsNil) s.BackingState = environ.(GetStater).GetStateInAPIServer() s.State, err = newState(environ, s.BackingState.MongoConnectionInfo()) c.Assert(err, gc.IsNil) s.APIState, err = juju.NewAPIState(environ, api.DialOpts{}) c.Assert(err, gc.IsNil) s.Environ = environ }
func (s *EnvConfigSuite) SetUpTest(c *gc.C) { s.FakeJujuHomeSuite.SetUpTest(c) s.envName = "test-env" s.client = &fakeEnvGetter{results: createBootstrapInfo(c, s.envName)} var err error s.store, err = configstore.Default() c.Assert(err, jc.ErrorIsNil) }
func (c *updateAllocationCommand) modelUUID() (string, error) { store, err := configstore.Default() if err != nil { return "", errors.Trace(err) } modelInfo, err := store.ReadInfo(c.ModelName()) if err != nil { return "", errors.Trace(err) } return modelInfo.APIEndpoint().ModelUUID, nil }
func getConfigstoreEnvironments() (set.Strings, error) { store, err := configstore.Default() if err != nil { return nil, errors.Annotate(err, "failed to get config store") } other, err := store.List() if err != nil { return nil, errors.Annotate(err, "failed to list environments in config store") } return set.NewStrings(other...), nil }
// NewConnFromName returns a Conn pointing at the environName environment, or the // default environment if not specified. func NewConnFromName(environName string) (*Conn, error) { store, err := configstore.Default() if err != nil { return nil, err } environ, err := environs.NewFromName(environName, store) if err != nil { return nil, err } return NewConn(environ) }
func newAPIClient(envName string, bClient *httpbakery.Client) (api.Connection, error) { store, err := configstore.Default() if err != nil { return nil, errors.Trace(err) } st, err := newAPIFromStore(envName, store, defaultAPIOpen, bClient) if err != nil { return nil, errors.Trace(err) } return st, nil }
func newAPIClient(envName string) (*api.State, error) { store, err := configstore.Default() if err != nil { return nil, errors.Trace(err) } st, err := newAPIFromStore(envName, store, defaultAPIOpen) if err != nil { return nil, errors.Trace(err) } return st.(*api.State), nil }
// resetJujuHome restores an new, clean Juju home environment without tools. func resetJujuHome(c *gc.C, envName string) environs.Environ { jenvDir := gitjujutesting.HomePath(".juju", "environments") err := os.RemoveAll(jenvDir) c.Assert(err, jc.ErrorIsNil) coretesting.WriteEnvironments(c, envConfig) dummy.Reset() store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) env, err := environs.PrepareFromName(envName, envcmd.BootstrapContext(cmdtesting.NullContext(c)), store) c.Assert(err, jc.ErrorIsNil) return env }
// resetJujuHome restores an new, clean Juju home environment without tools. func resetJujuHome(c *gc.C) environs.Environ { jenvDir := gitjujutesting.HomePath(".juju", "environments") err := os.RemoveAll(jenvDir) c.Assert(err, gc.IsNil) coretesting.WriteEnvironments(c, envConfig) dummy.Reset() store, err := configstore.Default() c.Assert(err, gc.IsNil) env, err := environs.PrepareFromName("peckham", cmdtesting.NullContext(c), store) c.Assert(err, gc.IsNil) envtesting.RemoveAllTools(c, env) return env }
func (s *cmdSystemSuite) TestSystemDestroy(c *gc.C) { st := s.Factory.MakeEnvironment(c, &factory.EnvParams{ Name: "just-a-system", ConfigAttrs: testing.Attrs{"state-server": true}, }) st.Close() s.run(c, "destroy", "dummyenv", "-y", "--destroy-all-environments") store, err := configstore.Default() _, err = store.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *cmdSystemSuite) TestSystemKill(c *gc.C) { st := s.Factory.MakeEnvironment(c, &factory.EnvParams{ Name: "foo", }) st.SwitchBlockOn(state.DestroyBlock, "TestBlockDestroyEnvironment") st.Close() s.run(c, "kill", "dummyenv", "-y") store, err := configstore.Default() _, err = store.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *SwitchSimpleSuite) addTestController(c *gc.C) { // First set up a controller in the config store. store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) info := store.CreateInfo("a-controller") info.SetAPIEndpoint(configstore.APIEndpoint{ Addresses: []string{"localhost"}, CACert: testing.CACert, ServerUUID: "server-uuid", }) err = info.Write() c.Assert(err, jc.ErrorIsNil) }
// Run implements Command.Run func (c *destroyCommand) Run(ctx *cmd.Context) error { store, err := configstore.Default() if err != nil { return errors.Annotate(err, "cannot open system info storage") } cfgInfo, err := store.ReadInfo(c.systemName) if err != nil { return errors.Annotate(err, "cannot read system info") } // Verify that we're destroying a system apiEndpoint := cfgInfo.APIEndpoint() if apiEndpoint.ServerUUID != "" && apiEndpoint.EnvironUUID != apiEndpoint.ServerUUID { return errors.Errorf("%q is not a system; use juju environment destroy to destroy it", c.systemName) } if !c.assumeYes { if err = confirmDestruction(ctx, c.systemName); err != nil { return err } } // Attempt to connect to the API. If we can't, fail the destroy. Users will // need to use the system kill command if we can't connect. api, err := c.getSystemAPI() if err != nil { return c.ensureUserFriendlyErrorLog(errors.Annotate(err, "cannot connect to API"), ctx, nil) } defer api.Close() // Obtain bootstrap / system environ information systemEnviron, err := c.getSystemEnviron(cfgInfo, api) if err != nil { return errors.Annotate(err, "cannot obtain bootstrap information") } // Attempt to destroy the system. err = api.DestroySystem(c.destroyEnvs, false) if params.IsCodeNotImplemented(err) { // Fall back to using the client endpoint to destroy the system, // sending the info we were already able to collect. return c.destroySystemViaClient(ctx, cfgInfo, systemEnviron, store) } if err != nil { return c.ensureUserFriendlyErrorLog(errors.Annotate(err, "cannot destroy system"), ctx, api) } return environs.Destroy(systemEnviron, store) }
func (s *SwitchSimpleSuite) addTestSystem(c *gc.C) { // First set up a system in the config store. s.SetFeatureFlags(feature.JES) store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) info := store.CreateInfo("a-system") info.SetAPIEndpoint(configstore.APIEndpoint{ Addresses: []string{"localhost"}, CACert: testing.CACert, ServerUUID: "server-uuid", }) err = info.Write() c.Assert(err, jc.ErrorIsNil) }
func (s *cmdControllerSuite) TestControllerKill(c *gc.C) { st := s.Factory.MakeModel(c, &factory.ModelParams{ Name: "foo", }) st.SwitchBlockOn(state.DestroyBlock, "TestBlockDestroyModel") st.Close() s.run(c, "kill-controller", "dummymodel", "-y") store, err := configstore.Default() _, err = store.ReadInfo("dummymodel") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *allocateSuite) SetUpTest(c *gc.C) { s.FakeJujuHomeSuite.SetUpTest(c) store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) info := store.CreateInfo(coretesting.SampleModelName) apiEndpoint := configstore.APIEndpoint{ ModelUUID: "env-uuid", } info.SetAPIEndpoint(apiEndpoint) err = info.Write() c.Assert(err, jc.ErrorIsNil) s.stub = &testing.Stub{} s.mockAPI = newMockAPI(s.stub) s.PatchValue(allocate.NewAPIClient, allocate.APIClientFnc(s.mockAPI)) }
func fakeBootstrapEnvironment(c *gc.C, envName string) { store, err := configstore.Default() c.Assert(err, gc.IsNil) envInfo := store.CreateInfo(envName) envInfo.SetBootstrapConfig(map[string]interface{}{"random": "extra data"}) envInfo.SetAPIEndpoint(configstore.APIEndpoint{ Addresses: []string{"localhost:12345"}, CACert: testing.CACert, }) envInfo.SetAPICredentials(configstore.APICredentials{ User: "******", Password: "******", }) err = envInfo.Write() c.Assert(err, gc.IsNil) }
func getConfigstoreOptions() (set.Strings, set.Strings, error) { store, err := configstore.Default() if err != nil { return nil, nil, errors.Annotate(err, "failed to get config store") } environmentNames, err := store.List() if err != nil { return nil, nil, errors.Annotate(err, "failed to list environments in config store") } controllerNames, err := store.ListSystems() if err != nil { return nil, nil, errors.Annotate(err, "failed to list controllers in config store") } // Also include the controllers. return set.NewStrings(environmentNames...), set.NewStrings(controllerNames...), nil }
func (s *syncToolsSuite) SetUpTest(c *gc.C) { s.FakeJujuHomeSuite.SetUpTest(c) // Create a target environments.yaml and make sure its environment is empty. coretesting.WriteEnvironments(c, ` environments: test-target: type: dummy state-server: false authorized-keys: "not-really-one" `) var err error s.configStore, err = configstore.Default() c.Assert(err, gc.IsNil) s.origSyncTools = syncTools }
func (s *DestroySuite) SetUpTest(c *gc.C) { s.FakeJujuHomeSuite.SetUpTest(c) s.clientapi = &fakeDestroyAPIClient{} s.api = &fakeDestroyAPI{} s.apierror = nil var err error s.store, err = configstore.Default() c.Assert(err, jc.ErrorIsNil) var envList = []struct { name string serverUUID string envUUID string bootstrapCfg map[string]interface{} }{ { name: "test1", serverUUID: "test1-uuid", envUUID: "test1-uuid", bootstrapCfg: createBootstrapInfo(c, "test1"), }, { name: "test2", serverUUID: "test1-uuid", envUUID: "test2-uuid", }, { name: "test3", envUUID: "test3-uuid", }, } for _, env := range envList { info := s.store.CreateInfo(env.name) info.SetAPIEndpoint(configstore.APIEndpoint{ Addresses: []string{"localhost"}, CACert: testing.CACert, EnvironUUID: env.envUUID, ServerUUID: env.serverUUID, }) if env.bootstrapCfg != nil { info.SetBootstrapConfig(env.bootstrapCfg) } err := info.Write() c.Assert(err, jc.ErrorIsNil) } }
func (c *JenvCommand) Run(ctx *cmd.Context) error { // Read data from the provided jenv file. data, err := c.jenvFile.Read(ctx) if err != nil { if os.IsNotExist(errors.Cause(err)) { return errors.NotFoundf("jenv file %q", c.jenvFile.Path) } return errors.Annotatef(err, "cannot read the provided jenv file %q", c.jenvFile.Path) } // Open the config store. store, err := configstore.Default() if err != nil { return errors.Annotate(err, "cannot get config store") } // Create and update the new environment info object. info := store.CreateInfo(c.envName) if err := updateEnvironmentInfo(info, data); err != nil { return errors.Annotatef(err, "invalid jenv file %q", c.jenvFile.Path) } // Write the environment info to JUJU_HOME. if err := info.Write(); err != nil { if errors.Cause(err) == configstore.ErrEnvironInfoAlreadyExists { descriptiveErr := errors.Errorf("an model named %q already exists: "+ "you can provide a second parameter to rename the model", c.envName) return errors.Wrap(err, descriptiveErr) } return errors.Annotate(err, "cannot write the jenv file") } // Switch to the new model. oldModelName, err := switchEnvironment(c.envName) if err != nil { return errors.Annotatef(err, "cannot switch to the new model %q", c.envName) } if oldModelName == "" { fmt.Fprintf(ctx.Stdout, "-> %s\n", c.envName) } else { fmt.Fprintf(ctx.Stdout, "%s -> %s\n", oldModelName, c.envName) } return nil }