mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
Use docker-credential-helper to manage secrets (WIP)
Store service credentials securely in the stores supported by docker: - https://github.com/docker/docker-credential-helpers#available-programs Introduces a top-level config property, "secretStore" and additional command line arguments to manage the stored secrets. The value of secretStore is used to find a helper command, `docker-credential-<secretStore>`. The docker project currently provides 4 store helpers: - "osxkeychain" (OS X only) - "secretservice" (Linux only) - "wincred" (Windows only) - "pass" (any OS supporting pass, which uses gpg2) Docker-for-desktop installs the credential helpers above, as well as "desktop" (docker-credential-desktop). Generic installation instructions for the helpers: - https://github.com/docker/docker-credential-helpers#installation Users could provide additional helpers, the only requirement is that the helper implements the credential store protocol: - https://github.com/docker/docker-credential-helpers#development The credential protocol is open, and new credential stores can be implemented by any CLI satisfying the protocol: - https://github.com/docker/docker-credential-helpers#development The modifications to existing modules is not tested due to lack of API keys, but demonstrates the unobtrusive changes required to use the secret store.
This commit is contained in:
parent
cc8f5f76ba
commit
b2982cc668
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