mirror of
				https://github.com/taigrr/wtf
				synced 2025-01-18 04:03:14 -08:00 
			
		
		
		
	Merge branch 'secret-store' of github.com:sam-github/wtf into sam-github-secret-store
This commit is contained in:
		
						commit
						c18bac3e27
					
				
							
								
								
									
										164
									
								
								cfg/secrets.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								cfg/secrets.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,164 @@
 | 
			
		||||
package cfg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"runtime"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker-credential-helpers/client"
 | 
			
		||||
	"github.com/docker/docker-credential-helpers/credentials"
 | 
			
		||||
	"github.com/olebedev/config"
 | 
			
		||||
	"github.com/wtfutil/wtf/logger"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Secret struct {
 | 
			
		||||
	Service  string
 | 
			
		||||
	Secret   string
 | 
			
		||||
	Username string
 | 
			
		||||
	Store    string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Configure the secret for a service.
 | 
			
		||||
//
 | 
			
		||||
// Does not overwrite explicitly configured values, so is safe to call
 | 
			
		||||
// if username and secret were explicitly set in module config.
 | 
			
		||||
//
 | 
			
		||||
// Input:
 | 
			
		||||
// * service: URL or identifier for service if configured by user. Not all
 | 
			
		||||
//   modules support or need this. Optional, defaults to serviceDefault.
 | 
			
		||||
// * serviceDefault: Default URL or identifier for service. Must be unique,
 | 
			
		||||
//   using the API URL is customary, but using the module name is reasonable.
 | 
			
		||||
//   Required, secrets cannot be stored unless associated with a service.
 | 
			
		||||
//
 | 
			
		||||
// Output:
 | 
			
		||||
// * username: If a user/subdomain/identifier specific to the service is
 | 
			
		||||
//   configurable, it can be saved as a "username". Optional.
 | 
			
		||||
// * secret: The secret for service. Optional.
 | 
			
		||||
func ConfigureSecret(
 | 
			
		||||
	globalConfig *config.Config,
 | 
			
		||||
	service string,
 | 
			
		||||
	serviceDefault string,
 | 
			
		||||
	username *string,
 | 
			
		||||
	secret *string, // unfortunate order dependency...
 | 
			
		||||
) {
 | 
			
		||||
	notWanted := func(out *string) bool {
 | 
			
		||||
		return out == nil && *out != ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Don't try to fetch from cred store if nothing is wanted.
 | 
			
		||||
	if notWanted(secret) && notWanted(username) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if service == "" {
 | 
			
		||||
		service = serviceDefault
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if service == "" {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cred, err := FetchSecret(globalConfig, service)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.Log(fmt.Sprintf("Loading secret failed: %s", err.Error()))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if cred == nil {
 | 
			
		||||
		// No secret store configued.
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if username != nil && *username == "" {
 | 
			
		||||
		*username = cred.Username
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if secret != nil && *secret == "" {
 | 
			
		||||
		*secret = cred.Secret
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fetch secret for `service`. Service is customarily a URL, but can be any
 | 
			
		||||
// identifier uniquely used by wtf to identify the service, such as the name
 | 
			
		||||
// of the module.  nil is returned if the secretStore global property is not
 | 
			
		||||
// present or the secret is not found in that store.
 | 
			
		||||
func FetchSecret(globalConfig *config.Config, service string) (*Secret, error) {
 | 
			
		||||
	prog := newProgram(globalConfig)
 | 
			
		||||
 | 
			
		||||
	if prog == nil {
 | 
			
		||||
		// No secret store configured.
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cred, err := client.Get(prog.runner, service)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("get %v from %v: %w", service, prog.store, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &Secret{
 | 
			
		||||
		Service:  cred.ServerURL,
 | 
			
		||||
		Secret:   cred.Secret,
 | 
			
		||||
		Username: cred.Username,
 | 
			
		||||
		Store:    prog.store,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func StoreSecret(globalConfig *config.Config, secret *Secret) error {
 | 
			
		||||
	prog := newProgram(globalConfig)
 | 
			
		||||
 | 
			
		||||
	if prog == nil {
 | 
			
		||||
		return errors.New("Cannot store secrets: wtf.secretStore is not configured")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cred := &credentials.Credentials{
 | 
			
		||||
		ServerURL: secret.Service,
 | 
			
		||||
		Username:  secret.Username,
 | 
			
		||||
		Secret:    secret.Secret,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// docker-credential requires a username, but it isn't necessary for
 | 
			
		||||
	// all services. Use a default if a username was not set.
 | 
			
		||||
	if cred.Username == "" {
 | 
			
		||||
		cred.Username = "default"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := client.Store(prog.runner, cred)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("store %v: %w", prog.store, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type program struct {
 | 
			
		||||
	store  string
 | 
			
		||||
	runner client.ProgramFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newProgram(globalConfig *config.Config) *program {
 | 
			
		||||
	secretStore := globalConfig.UString("wtf.secretStore", "(none)")
 | 
			
		||||
 | 
			
		||||
	if secretStore == "(none)" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if secretStore == "" {
 | 
			
		||||
		switch runtime.GOOS {
 | 
			
		||||
		case "windows":
 | 
			
		||||
			secretStore = "winrt"
 | 
			
		||||
		case "darwin":
 | 
			
		||||
			secretStore = "osxkeychain"
 | 
			
		||||
		default:
 | 
			
		||||
			secretStore = "secretservice"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &program{
 | 
			
		||||
		secretStore,
 | 
			
		||||
		client.NewShellProgramFunc("docker-credential-" + secretStore),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +1,13 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/chzyer/readline"
 | 
			
		||||
	goFlags "github.com/jessevdk/go-flags"
 | 
			
		||||
	"github.com/olebedev/config"
 | 
			
		||||
	"github.com/wtfutil/wtf/cfg"
 | 
			
		||||
@ -17,10 +20,29 @@ type Flags struct {
 | 
			
		||||
	Module  string `short:"m" long:"module" optional:"yes" description:"Display info about a specific module, i.e.: 'wtfutil -m=todo'"`
 | 
			
		||||
	Profile bool   `short:"p" long:"profile" optional:"yes" description:"Profile application memory usage"`
 | 
			
		||||
	Version bool   `short:"v" long:"version" description:"Show version info"`
 | 
			
		||||
	// Work-around go-flags misfeatures. If any sub-command is defined
 | 
			
		||||
	// then `wtf` (no sub-commands, the common usage), is warned about.
 | 
			
		||||
	Opt struct {
 | 
			
		||||
		Cmd  string   `positional-arg-name:"command"`
 | 
			
		||||
		Args []string `positional-arg-name:"args"`
 | 
			
		||||
	} `positional-args:"yes"`
 | 
			
		||||
 | 
			
		||||
	hasCustom bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var EXTRA = `
 | 
			
		||||
Commands:
 | 
			
		||||
  save-secret <service> [secret [username]]
 | 
			
		||||
    service      Service URL or name for secret.
 | 
			
		||||
    secret       Secret to be saved for the service.
 | 
			
		||||
    username     Username to associate with the service.
 | 
			
		||||
  Save a secret into the secret store.  Requires wtf.secretStore
 | 
			
		||||
  to be configured.  See individual modules for information on what
 | 
			
		||||
  service, secret, and username means for their configuration. Not
 | 
			
		||||
  all modules use secrets, and not all secrets require a username.
 | 
			
		||||
  If secret or username is not provided, will prompt for them.
 | 
			
		||||
`
 | 
			
		||||
 | 
			
		||||
// NewFlags creates an instance of Flags
 | 
			
		||||
func NewFlags() *Flags {
 | 
			
		||||
	flags := Flags{}
 | 
			
		||||
@ -46,6 +68,71 @@ func (flags *Flags) RenderIf(version, date string, config *config.Config) {
 | 
			
		||||
		fmt.Println(fmt.Sprintf("%s (%s)", version, date))
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if flags.Opt.Cmd == "" {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch cmd := flags.Opt.Cmd; cmd {
 | 
			
		||||
	case "save-secret":
 | 
			
		||||
		var service, secret, username string
 | 
			
		||||
		args := flags.Opt.Args
 | 
			
		||||
 | 
			
		||||
		if len(args) < 1 || args[0] == "" {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, "save-secret: service required, see `%s --help`\n", os.Args[0])
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		service = args[0]
 | 
			
		||||
 | 
			
		||||
		if len(args) > 1 {
 | 
			
		||||
			secret = args[1]
 | 
			
		||||
		} else {
 | 
			
		||||
			b, err := readline.Password("Secret (required): ")
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				fmt.Fprintf(os.Stderr, "Error: %v\n", err)
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
			}
 | 
			
		||||
			secret = string(b)
 | 
			
		||||
		}
 | 
			
		||||
		secret = strings.TrimSpace(secret)
 | 
			
		||||
 | 
			
		||||
		if secret == "" {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, "save-secret: secret required, see `%s --help`\n", os.Args[0])
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(args) > 2 {
 | 
			
		||||
			username = args[2]
 | 
			
		||||
		} else {
 | 
			
		||||
			fmt.Printf("Username (optional): ")
 | 
			
		||||
			reader := bufio.NewReader(os.Stdin)
 | 
			
		||||
			var err error
 | 
			
		||||
			username, err = reader.ReadString('\n')
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				fmt.Fprintf(os.Stderr, "Error: %v\n", err)
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		username = strings.TrimSpace(username)
 | 
			
		||||
 | 
			
		||||
		err := cfg.StoreSecret(config, &cfg.Secret{
 | 
			
		||||
			Service:  service,
 | 
			
		||||
			Secret:   secret,
 | 
			
		||||
			Username: username,
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, "Saving secret for service %q: %s\n", service, err.Error())
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Printf("Saved secret for service %q (username %q)\n", service, username)
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	default:
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "Command `%s` is not supported, try `%s --help`\n", cmd, os.Args[0])
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasCustomConfig returns TRUE if a config path was passed in, FALSE if one was not
 | 
			
		||||
@ -68,6 +155,7 @@ func (flags *Flags) Parse() {
 | 
			
		||||
	parser := goFlags.NewParser(flags, goFlags.Default)
 | 
			
		||||
	if _, err := parser.Parse(); err != nil {
 | 
			
		||||
		if flagsErr, ok := err.(*goFlags.Error); ok && flagsErr.Type == goFlags.ErrHelp {
 | 
			
		||||
			fmt.Println(EXTRA)
 | 
			
		||||
			os.Exit(0)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@ -15,9 +15,11 @@ require (
 | 
			
		||||
	github.com/andygrunwald/go-gerrit v0.0.0-20190825170856-5959a9bf9ff8
 | 
			
		||||
	github.com/briandowns/openweathermap v0.0.0-20180804155945-5f41b7c9d92d
 | 
			
		||||
	github.com/cenkalti/backoff v2.2.1+incompatible // indirect
 | 
			
		||||
	github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3
 | 
			
		||||
	github.com/digitalocean/godo v1.35.1
 | 
			
		||||
	github.com/docker/distribution v2.7.1+incompatible // indirect
 | 
			
		||||
	github.com/docker/docker v1.13.1
 | 
			
		||||
	github.com/docker/docker-credential-helpers v0.6.3
 | 
			
		||||
	github.com/docker/go-connections v0.4.0 // indirect
 | 
			
		||||
	github.com/docker/go-units v0.4.0 // indirect
 | 
			
		||||
	github.com/dustin/go-humanize v1.0.0
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.sum
									
									
									
									
									
								
							@ -101,6 +101,7 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH
 | 
			
		||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 | 
			
		||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 | 
			
		||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 | 
			
		||||
github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3 h1:T7Bw4H6z3WAZ2khw+gfKdYmbKHyy5xiHtk9IHfZqm7g=
 | 
			
		||||
github.com/chzyer/readline v0.0.0-20171208011716-f6d7a1f6fbf3/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 | 
			
		||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 | 
			
		||||
github.com/circonus-labs/circonus-gometrics v2.2.4+incompatible h1:+ZwGzyJGsOwSxIEDDOXzPagR167tQak/1P5wBwH+/dM=
 | 
			
		||||
@ -141,6 +142,8 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU
 | 
			
		||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
			
		||||
github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
 | 
			
		||||
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
 | 
			
		||||
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 | 
			
		||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
 | 
			
		||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 | 
			
		||||
 | 
			
		||||
@ -35,5 +35,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		projectName: ymlConfig.UString("projectName", os.Getenv("WTF_AZURE_DEVOPS_PROJECT_NAME")),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.orgURL,
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.projectName,
 | 
			
		||||
		&settings.apiToken,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,5 +27,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		subdomain: ymlConfig.UString("subdomain", os.Getenv("WTF_BAMBOO_HR_SUBDOMAIN")),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"",
 | 
			
		||||
		name,
 | 
			
		||||
		&settings.subdomain,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
package buildkite
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/olebedev/config"
 | 
			
		||||
	"github.com/wtfutil/wtf/cfg"
 | 
			
		||||
	"github.com/wtfutil/wtf/utils"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@ -35,6 +36,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		pipelines: buildPipelineSettings(ymlConfig),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"",
 | 
			
		||||
		name,
 | 
			
		||||
		&settings.orgSlug,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,5 +26,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_CIRCLE_API_KEY"))),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"",
 | 
			
		||||
		name,
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,5 +30,21 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		tags:           ymlConfig.UList("monitors.tags"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"",
 | 
			
		||||
		"datadog-api",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"",
 | 
			
		||||
		"datadog-app",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.applicationKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,5 +31,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		dateFormat: ymlConfig.UString("dateFormat", wtf.DateFormat),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"",
 | 
			
		||||
		name,
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -33,5 +33,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		matchesTo:     ymlConfig.UInt("matchesTo", 5),
 | 
			
		||||
		standingCount: ymlConfig.UInt("standingCount", 5),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"",
 | 
			
		||||
		name,
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		verifyServerCertificate: ymlConfig.UBool("verifyServerCertificate", true),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.domain,
 | 
			
		||||
		name,
 | 
			
		||||
		nil, // Seems like it should be mandatory, but its optional above.
 | 
			
		||||
		&settings.password,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	settings.colors.rows.even = ymlConfig.UString("colors.rows.even", "white")
 | 
			
		||||
	settings.colors.rows.odd = ymlConfig.UString("colors.rows.odd", "blue")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ type Settings struct {
 | 
			
		||||
	common *cfg.Common
 | 
			
		||||
 | 
			
		||||
	apiKey        string        `help:"Your GitHub API token."`
 | 
			
		||||
	apiSecret     string        `help:"Secret store for your GitHub API token."`
 | 
			
		||||
	baseURL       string        `help:"Your GitHub Enterprise API URL." optional:"true"`
 | 
			
		||||
	customQueries []customQuery `help:"Custom queries allow you to filter pull requests and issues however you like. Give the query a title and a filter. Filters can be copied directly from GitHub’s UI." optional:"true"`
 | 
			
		||||
	enableStatus  bool          `help:"Display pull request mergeability status (‘dirty’, ‘clean’, ‘unstable’, ‘blocked’)." optional:"true"`
 | 
			
		||||
@ -45,6 +46,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
	settings.repositories = cfg.ParseAsMapOrList(ymlConfig, "repositories")
 | 
			
		||||
	settings.customQueries = parseCustomQueries(ymlConfig)
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.baseURL,
 | 
			
		||||
		name,
 | 
			
		||||
		&settings.username,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		username: ymlConfig.UString("username"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.domain,
 | 
			
		||||
		name,
 | 
			
		||||
		&settings.username,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	settings.projects = cfg.ParseAsMapOrList(ymlConfig, "projects")
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
 | 
			
		||||
@ -32,5 +32,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		showProject:   ymlConfig.UBool("showProject", true),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.domain,
 | 
			
		||||
		name,
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,5 +30,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		roomURI:          ymlConfig.UString("roomUri", "wtfutil/Lobby"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://api.gitter.im",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.apiToken,
 | 
			
		||||
		nil,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		since:    ymlConfig.UString("since", ""),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://haveibeenpwned.com/api",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
		nil,
 | 
			
		||||
	)
 | 
			
		||||
	settings.colors.ok = ymlConfig.UString("colors.ok", "white")
 | 
			
		||||
	settings.colors.pwned = ymlConfig.UString("colors.pwned", "red")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,5 +36,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		verifyServerCertificate: ymlConfig.UBool("verifyServerCertificate", true),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.url,
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.user,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,6 +45,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		verifyServerCertificate: ymlConfig.UBool("verifyServerCertificate", true),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.domain,
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.username,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	settings.colors.rows.even = ymlConfig.UString("colors.even", "lightblue")
 | 
			
		||||
	settings.colors.rows.odd = ymlConfig.UString("colors.odd", "white")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -30,5 +30,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		applicationIDs: ymlConfig.UList("applicationIDs"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"newrelic.com",
 | 
			
		||||
		"",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		scheduleIdentifierType: ymlConfig.UString("scheduleIdentifierType", "id"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://opsgenie.com",
 | 
			
		||||
		"",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	settings.schedule = settings.arrayifySchedules(ymlConfig, globalConfig)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
 | 
			
		||||
@ -37,5 +37,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		showSchedules:    ymlConfig.UBool("showSchedules", true),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://pagerduty.com",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.myName,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,5 +34,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		maxDomainWidth: ymlConfig.UInt("maxDomainWidth", 20),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		settings.apiUrl,
 | 
			
		||||
		"",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.token,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,5 +23,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		consumerKey: ymlConfig.UString("consumerKey"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://pocket.com",
 | 
			
		||||
		"",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.consumerKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,5 +34,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		projectOwner:   ymlConfig.UString("projectOwner"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://rollbar.com",
 | 
			
		||||
		"",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.accessToken,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,5 +30,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		secretKey:    ymlConfig.UString("secretKey", os.Getenv("SPOTIFY_SECRET")),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://spotify.com",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.clientID,
 | 
			
		||||
		&settings.secretKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,5 +30,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		projects: utils.IntsToUints(utils.ToInts(ymlConfig.UList("projects"))),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://todoist.com",
 | 
			
		||||
		"",
 | 
			
		||||
		nil,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,5 +35,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		sort_by: ymlConfig.UString("sort_by", "id:desc"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://travis.com",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.baseURL,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,14 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		username:    ymlConfig.UString("username"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://trello.com",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.accessToken,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	settings.list = buildLists(ymlConfig, globalConfig)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
 | 
			
		||||
@ -29,5 +29,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		team:   ymlConfig.UString("team"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://victorops.com",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.apiID,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,5 +31,13 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co
 | 
			
		||||
		username:  ymlConfig.UString("username"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg.ConfigureSecret(
 | 
			
		||||
		globalConfig,
 | 
			
		||||
		"https://zendesk.com",
 | 
			
		||||
		"",
 | 
			
		||||
		&settings.subdomain,
 | 
			
		||||
		&settings.apiKey,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	return &settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user