Example #1
0
func findAuthOpts(c *cli.Context, have map[string]commandoptions.Cred, want map[string]string) error {
	// use command-line options if available
	commandoptions.CLIopts(c, have, want)
	// are there any unset auth variables?
	if len(want) != 0 {
		// if so, look in config file
		err := commandoptions.ConfigFile(c, have, want)
		if err != nil {
			return err
		}
		// still unset auth variables?
		if len(want) != 0 {
			// if so, look in environment variables
			envvars(have, want)
		}
	}

	return nil
}
Example #2
0
func (ctx *Context) handleGlobalOptions() error {
	defaultSection, err := commandoptions.ProfileSection("")
	if err != nil {
		return err
	}

	defaultKeysHash := map[string]string{}
	if defaultSection != nil {
		defaultKeysHash = defaultSection.KeysHash()
	}

	have := make(map[string]commandoptions.Cred)
	want := map[string]string{
		"output":    "",
		"no-cache":  "",
		"no-header": "",
		"log":       "",
	}

	// use command-line options if available
	commandoptions.CLIopts(ctx.CLIContext, have, want)
	// are there any unset auth variables?
	if len(want) != 0 {
		// if so, look in config file
		err := commandoptions.ConfigFile(ctx.CLIContext, have, want)
		if err != nil {
			return err
		}
	}

	var outputFormat string
	if ctx.CLIContext.IsSet("output") {
		outputFormat = ctx.CLIContext.String("output")
	} else if value, ok := defaultKeysHash["output"]; ok && value != "" {
		outputFormat = value
	} else {
		have["output"] = commandoptions.Cred{
			Value: "table",
			From:  "default value",
		}
		outputFormat = "table"
	}
	switch outputFormat {
	case "json", "csv", "table":
		ctx.GlobalOptions.output = outputFormat
	default:
		return fmt.Errorf("Invalid value for `output` flag: '%s'. Options are: json, csv, table.", outputFormat)
	}

	if ctx.CLIContext.IsSet("no-header") {
		ctx.GlobalOptions.noHeader = true
	} else if value, ok := defaultKeysHash["no-header"]; ok && value != "" {
		ctx.GlobalOptions.noHeader = true
	}

	if ctx.CLIContext.IsSet("no-cache") {
		ctx.GlobalOptions.noCache = true
	} else if value, ok := defaultKeysHash["no-cache"]; ok && value != "" {
		ctx.GlobalOptions.noCache = true
	}

	var logLevel string
	if ctx.CLIContext.IsSet("log") {
		logLevel = ctx.CLIContext.String("log")
	} else if value, ok := defaultKeysHash["log"]; ok && value != "" {
		logLevel = value
	}
	var level logrus.Level
	if logLevel != "" {
		switch strings.ToLower(logLevel) {
		case "debug":
			level = logrus.DebugLevel
		case "info":
			level = logrus.InfoLevel
		default:
			return fmt.Errorf("Invalid value for `log` flag: %s. Valid options are: debug, info", logLevel)
		}
	}
	ctx.logger = &logrus.Logger{
		Out:       ctx.CLIContext.App.Writer,
		Formatter: &logrus.TextFormatter{},
		Level:     level,
	}

	haveString := ""
	for k, v := range have {
		haveString += fmt.Sprintf("%s: %s (from %s)\n", k, v.Value, v.From)
	}
	ctx.logger.Infof("Global Options:\n%s\n", haveString)

	return nil
}
Example #3
0
// Credentials determines the appropriate authentication method for the user.
// It returns a gophercloud.AuthOptions object and a region.
//
// It will use command-line authentication parameters if available, then it will
// look for any unset parameters in the config file, and then finally in
// environment variables.
func Credentials(c *cli.Context, logger *logrus.Logger) (*CredentialsResult, error) {
	ao := &gophercloud.AuthOptions{
		AllowReauth: true,
	}

	have := make(map[string]commandoptions.Cred)

	// let's looks for a region and identity endpoint
	want := map[string]string{
		"auth-url": "",
		"region":   "",
	}

	err := findAuthOpts(c, have, want)
	if err != nil {
		return nil, err
	}

	// if the user didn't provide an auth URL, default to the Rackspace US endpoint
	if _, ok := have["auth-url"]; !ok || have["auth-url"].Value == "" {
		have["auth-url"] = commandoptions.Cred{Value: rackspace.RackspaceUSIdentity, From: "default value"}
		delete(want, "auth-url")
	}
	ao.IdentityEndpoint = have["auth-url"].Value

	// upper-case the region
	region := strings.ToUpper(have["region"].Value)
	delete(want, "region")

	// now we check for token authentication (only allowed via the command-line)
	want["auth-tenant-id"] = ""
	want["auth-token"] = ""
	commandoptions.CLIopts(c, have, want)

	// if a tenant ID was provided on the command-line, we don't bother checking for a
	// username or api key
	if have["auth-tenant-id"].Value != "" || have["auth-token"].Value != "" {
		if tenantID, ok := have["auth-tenant-id"]; ok {
			ao.TenantID = tenantID.Value
			ao.TokenID = have["auth-token"].Value
			delete(want, "auth-token")
		} else {
			return nil, Err(have, want, tenantIDAuthErrSlice)
		}
	} else {
		// otherwise, let's look for a username and API key
		want = map[string]string{
			"username": "",
			"api-key":  "",
		}
		err = findAuthOpts(c, have, want)
		if err != nil {
			return nil, err
		}
		if have["username"].Value != "" || have["api-key"].Value != "" {
			if username, ok := have["username"]; ok {
				ao.Username = username.Value
				ao.APIKey = have["api-key"].Value
				delete(want, "api-key")
			} else {
				return nil, Err(have, want, usernameAuthErrSlice)
			}
		} else {
			return nil, Err(have, want, usernameAuthErrSlice)
		}
	}

	if logger != nil {
		haveString := ""
		for k, v := range have {
			haveString += fmt.Sprintf("%s: %s (from %s)\n", k, v.Value, v.From)
		}
		logger.Infof("Authentication Credentials:\n%s\n", haveString)
	}

	credsResult := &CredentialsResult{
		AuthOpts: ao,
		Region:   region,
		Have:     have,
		Want:     want,
	}

	return credsResult, nil
}