func (c *imageMetadataCommandBase) prepare(context *cmd.Context) (environs.Environ, error) { // NOTE(axw) this is a work-around for the TODO below. This // means that the command will only work if you've bootstrapped // the specified environment. bootstrapConfig, params, err := modelcmd.NewGetBootstrapConfigParamsFunc(context, c.ClientStore())(c.ControllerName()) if err != nil { return nil, errors.Trace(err) } provider, err := environs.Provider(bootstrapConfig.CloudType) if err != nil { return nil, errors.Trace(err) } cfg, err := provider.PrepareConfig(*params) if err != nil { return nil, errors.Trace(err) } // TODO(axw) we'll need to revise the metadata commands to work // without preparing an environment. They should take the same // format as bootstrap, i.e. cloud/region, and we'll use that to // identify region and endpoint info that we need. Not sure what // we'll do about simplestreams.MetadataValidator yet. Probably // move it to the EnvironProvider interface. return environs.New(environs.OpenParams{ Cloud: params.Cloud, Config: cfg, }) }
func (c *destroyCommandBase) getControllerEnvironFromStore( ctx *cmd.Context, store jujuclient.ClientStore, controllerName string, ) (environs.Environ, error) { bootstrapConfig, params, err := modelcmd.NewGetBootstrapConfigParamsFunc(ctx, store)(controllerName) if err != nil { return nil, errors.Trace(err) } provider, err := environs.Provider(bootstrapConfig.CloudType) if err != nil { return nil, errors.Trace(err) } cfg, err := provider.PrepareConfig(*params) if err != nil { return nil, errors.Trace(err) } return environs.New(environs.OpenParams{ Cloud: params.Cloud, Config: cfg, }) }
// getRebootstrapParams returns the params for rebootstrapping the // specified controller. func (c *restoreCommand) getRebootstrapParams( ctx *cmd.Context, controllerName string, meta *params.BackupsMetadataResult, ) (*restoreBootstrapParams, error) { // TODO(axw) delete this and -b. We will update bootstrap with a flag // to specify a restore file. When we do that, we'll need to extract // the CA cert from the backup, and we'll need to reset the password // after restore so the admin user can login. We also need to store // things like the admin-secret, controller certificate etc with the // backup. store := c.ClientStore() controllerDetails, err := store.ControllerByName(controllerName) if err != nil { return nil, errors.Trace(err) } config, params, err := modelcmd.NewGetBootstrapConfigParamsFunc(ctx, store)(controllerName) if err != nil { return nil, errors.Trace(err) } provider, err := environs.Provider(config.CloudType) if err != nil { return nil, errors.Trace(err) } cfg, err := provider.PrepareConfig(*params) if err != nil { return nil, errors.Trace(err) } // Get the local admin user so we can use the password as the admin secret. // TODO(axw) check that account.User is environs.AdminUser. var adminSecret string account, err := store.AccountDetails(controllerName) if err == nil { adminSecret = account.Password } else if errors.IsNotFound(err) { // No relevant local admin user so generate a new secret. buf := make([]byte, 16) if _, err := io.ReadFull(rand.Reader, buf); err != nil { return nil, errors.Annotate(err, "generating new admin secret") } adminSecret = fmt.Sprintf("%x", buf) } else { return nil, errors.Trace(err) } // Turn on safe mode so that the newly bootstrapped instance // will not destroy all the instances it does not know about. // Also set the admin secret and ca cert info. cfg, err = cfg.Apply(map[string]interface{}{ "provisioner-safe-mode": true, }) if err != nil { return nil, errors.Annotatef(err, "cannot enable provisioner-safe-mode") } controllerCfg := make(controller.Config) for k, v := range config.ControllerConfig { controllerCfg[k] = v } controllerCfg[controller.ControllerUUIDKey] = controllerDetails.ControllerUUID controllerCfg[controller.CACertKey] = meta.CACert return &restoreBootstrapParams{ controllerCfg, params.Cloud, config.Credential, adminSecret, cfg, }, nil }