Example #1
0
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)
}
Example #2
0
// Config returns the configuration for the environment; obtaining bootstrap
// information from the API if necessary.  If callers already have an active
// client API connection, it will be used.  Otherwise, a new API connection will
// be used if necessary.
func (c *ModelCommandBase) Config(store configstore.Storage, client ModelGetter) (*config.Config, error) {
	if c.modelName == "" {
		return nil, errors.Trace(ErrNoModelSpecified)
	}
	cfg, _, err := environs.ConfigForName(c.modelName, store)
	if err == nil {
		return cfg, nil
	} else if !environs.IsEmptyConfig(err) {
		return nil, errors.Trace(err)
	}

	if client == nil {
		client, err = c.NewModelGetter()
		if err != nil {
			return nil, errors.Trace(err)
		}
		defer client.Close()
	}

	bootstrapCfg, err := client.ModelGet()
	if err != nil {
		return nil, errors.Trace(err)
	}
	return config.New(config.NoDefaults, bootstrapCfg)
}