func (c *setDefaultRegionCommand) Run(ctxt *cmd.Context) error { cloudDetails, err := cloudOrProvider(c.cloud, jujucloud.CloudByName) if err != nil { return err } if len(cloudDetails.Regions) == 0 { return errors.Errorf("cloud %s has no regions", c.cloud) } if !hasRegion(c.region, cloudDetails.Regions) { var regionNames []string for _, r := range cloudDetails.Regions { regionNames = append(regionNames, r.Name) } return errors.NewNotValid( nil, fmt.Sprintf("region %q for cloud %s not valid, valid regions are %s", c.region, c.cloud, strings.Join(regionNames, ", "))) } var cred *jujucloud.CloudCredential cred, err = c.store.CredentialForCloud(c.cloud) if errors.IsNotFound(err) { cred = &jujucloud.CloudCredential{} } else if err != nil { return err } cred.DefaultRegion = c.region if err := c.store.UpdateCredential(c.cloud, *cred); err != nil { return err } ctxt.Infof("Default region in %s set to %q.", c.cloud, c.region) return nil }
// DetectCredentials is part of the environs.ProviderCredentials interface. func (e environProviderCredentials) DetectCredentials() (*cloud.CloudCredential, error) { dir := credentialsDir() credsFile := filepath.Join(dir, "credentials") credInfo, err := ini.LooseLoad(credsFile) if err != nil { return nil, errors.Annotate(err, "loading AWS credentials file") } credInfo.NameMapper = ini.TitleUnderscore // There's always a section called "DEFAULT" for top level items. if len(credInfo.Sections()) == 1 { // No standard AWS credentials so try environment variables. return e.detectEnvCredentials() } type accessKeyValues struct { AwsAccessKeyId string AwsSecretAccessKey string } result := cloud.CloudCredential{ AuthCredentials: make(map[string]cloud.Credential), } for _, credName := range credInfo.SectionStrings() { if credName == ini.DEFAULT_SECTION { // No credentials at top level. continue } values := new(accessKeyValues) if err := credInfo.Section(credName).MapTo(values); err != nil { return nil, errors.Annotatef(err, "invalid credential attributes in section %q", credName) } // Basic validation check if values.AwsAccessKeyId == "" || values.AwsSecretAccessKey == "" { logger.Errorf("missing aws credential attributes in credentials file section %q", credName) continue } accessKeyCredential := cloud.NewCredential( cloud.AccessKeyAuthType, map[string]string{ "access-key": values.AwsAccessKeyId, "secret-key": values.AwsSecretAccessKey, }, ) accessKeyCredential.Label = fmt.Sprintf("aws credential %q", credName) result.AuthCredentials[credName] = accessKeyCredential } // See if there's also a default region defined. configFile := filepath.Join(dir, "config") configInfo, err := ini.LooseLoad(configFile) if err != nil { return nil, errors.Annotate(err, "loading AWS config file") } result.DefaultRegion = configInfo.Section("default").Key("region").String() return &result, nil }
// UpdateCredential implements CredentialUpdater. func (s *store) UpdateCredential(cloudName string, details cloud.CloudCredential) error { releaser, err := s.acquireLock() if err != nil { return errors.Annotatef(err, "cannot update credentials for %v", cloudName) } defer releaser.Release() all, err := ReadCredentialsFile(JujuCredentialsPath()) if err != nil { return errors.Annotate(err, "cannot get credentials") } if len(all) == 0 { all = make(map[string]cloud.CloudCredential) } // Clear the default credential if we are removing that one. if existing, ok := all[cloudName]; ok && existing.DefaultCredential != "" { stillHaveDefault := false for name := range details.AuthCredentials { if name == existing.DefaultCredential { stillHaveDefault = true break } } if !stillHaveDefault { details.DefaultCredential = "" } } all[cloudName] = details return WriteCredentialsFile(all) }
// DetectCredentials is part of the environs.ProviderCredentials interface. func (c OpenstackCredentials) DetectCredentials() (*cloud.CloudCredential, error) { result := cloud.CloudCredential{ AuthCredentials: make(map[string]cloud.Credential), } // Try just using environment variables creds, user, region, err := c.detectCredential() if err == nil { result.DefaultRegion = region result.AuthCredentials[user] = *creds } // Now look for .novarc file in home dir. novarc := filepath.Join(utils.Home(), ".novarc") novaInfo, err := ini.LooseLoad(novarc) if err != nil { return nil, errors.Annotate(err, "loading novarc file") } stripExport := regexp.MustCompile(`(?i)^\s*export\s*`) keyValues := novaInfo.Section(ini.DEFAULT_SECTION).KeysHash() if len(keyValues) > 0 { for k, v := range keyValues { k = stripExport.ReplaceAllString(k, "") os.Setenv(k, v) } creds, user, region, err := c.detectCredential() if err == nil { result.DefaultRegion = region result.AuthCredentials[user] = *creds } } if len(result.AuthCredentials) == 0 { return nil, errors.NotFoundf("openstack credentials") } return &result, nil }