func initAuth() {
	if authInitialized {
		return
	}
	authInitialized = true
	InitCredentialsFile()
	authCommand = &cobra.Command{
		Use:   "auth",
		Short: "Authentication settings",
	}
	Root.AddCommand(authCommand)
	authAddCommand = &cobra.Command{
		Use:     "add-profile",
		Aliases: []string{"add"},
		Short:   "Add user profile for authentication",
	}
	authCommand.AddCommand(authAddCommand)
	authCommand.AddCommand(&cobra.Command{
		Use:     "list-profiles",
		Aliases: []string{"ls"},
		Short:   "List available configured authentication profiles",
		Args:    cobra.NoArgs,
		Run: func(cmd *cobra.Command, args []string) {
			profiles := Creds.GetStringMap("profiles")
			if profiles != nil {
				types := make(map[string]bool)
				for _, v := range profiles {
					if typeName := v.(map[string]interface{})["type"]; typeName != nil {
						types[typeName.(string)] = true
					}
				}
				for typeName := range types {
					handler := AuthHandlers[typeName]
					if handler == nil {
						continue
					}
					listKeys := handler.ProfileKeys()
					table := tablewriter.NewWriter(os.Stdout)
					table.SetHeader(append([]string{fmt.Sprintf("%s Profile Name", typeName)}, listKeys...))
					for name, p := range profiles {
						profile := p.(map[string]interface{})
						if ptype := profile["type"]; ptype == nil || ptype.(string) != typeName {
							continue
						}
						row := []string{name}
						for _, key := range listKeys {
							row = append(row, profile[strings.Replace(key, "-", "_", -1)].(string))
						}
						table.Append(row)
					}
					table.Render()
				}
			} else {
				fmt.Printf("No profiles configured. Use `%s auth add-profile` to add one.\n", Root.CommandPath())
			}
		},
	})
	Client.UseRequest(func(ctx *context.Context, h context.Handler) {
		profile := GetProfile()
		handler := AuthHandlers[profile["type"]]
		if handler == nil {
			h.Error(ctx, fmt.Errorf("no handler for auth type %s", profile["type"]))
			return
		}
		if err := handler.OnRequest(ctx.Get("log").(*zerolog.Logger), ctx.Request); err != nil {
			h.Error(ctx, err)
			return
		}
		h.Next(ctx)
	})
}
initAuth sets up basic commands and the credentials file so that new auth
handlers can be registered. This is safe to call many times.
package cli
import (
	"fmt"
	"net/http"
	"os"
	"path"
	"strings"
	"github.com/olekukonko/tablewriter"
	"github.com/rs/zerolog"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"gopkg.in/h2non/gentleman.v2/context"
)
type AuthHandler interface {
	ProfileKeys() []string
	OnRequest(log *zerolog.Logger, request *http.Request) error
}
var AuthHandlers = make(map[string]AuthHandler)
var authInitialized bool
var authCommand *cobra.Command
var authAddCommand *cobra.Command