115 lines
2.5 KiB
Go
115 lines
2.5 KiB
Go
package secret
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Provider for secrets.
|
|
type Provider interface {
|
|
// GetSecret loads a secret by named key.
|
|
GetSecret(key string) (value []byte, err error)
|
|
}
|
|
|
|
// AmbiguousKey is an error incdicating that the secret doesn't resolve to exactly one item.
|
|
type AmbiguousKey struct {
|
|
Key string
|
|
}
|
|
|
|
func (err AmbiguousKey) Error() string {
|
|
return fmt.Sprintf("secret: ambigious secret key %q", err.Key)
|
|
}
|
|
|
|
// NotFound is an error indicating the secret can not be found.
|
|
type NotFound struct {
|
|
Key string
|
|
}
|
|
|
|
func (err NotFound) Error() string {
|
|
if err.Key == "" {
|
|
return "secret: not found"
|
|
}
|
|
return fmt.Sprintf("secret: %q not found", err.Key)
|
|
}
|
|
|
|
// ToBinary converts a string to []bytes.
|
|
//
|
|
// There are special prefixes for binary encoded formats:
|
|
// - hex: for hexadecimal encoded strings
|
|
// - b64: for base-64 encoded strings (raw encoding)
|
|
//
|
|
// If a special prefix is found, the appropriate codec will be used to decode to string to []byte,
|
|
// when there is an error decoding, it may result in an empty value.
|
|
//
|
|
// All other strings will be converted to []byte as-is.
|
|
func ToBinary(s string) (bytes []byte) {
|
|
switch {
|
|
case strings.HasPrefix(s, "hex:"):
|
|
bytes, _ = hex.DecodeString(s[4:])
|
|
case strings.HasPrefix(s, "b64:"):
|
|
bytes, _ = base64.RawStdEncoding.DecodeString(s[4:])
|
|
default:
|
|
bytes = []byte(s)
|
|
}
|
|
return
|
|
}
|
|
|
|
type providerOptions struct {
|
|
timeout time.Duration
|
|
apiKey string
|
|
credentials string
|
|
clientID string
|
|
secretID string
|
|
region string
|
|
}
|
|
|
|
// Option for providers.
|
|
type Option func(*providerOptions)
|
|
|
|
func newProviderOptions(opts ...Option) *providerOptions {
|
|
options := new(providerOptions)
|
|
for _, opt := range opts {
|
|
opt(options)
|
|
}
|
|
return options
|
|
}
|
|
|
|
// WithAPIKey sets the provider API key.
|
|
func WithAPIKey(key string) Option {
|
|
return func(p *providerOptions) {
|
|
p.apiKey = key
|
|
}
|
|
}
|
|
|
|
// WithCredentials specifies the API credentials.
|
|
func WithCredentials(credentials string) Option {
|
|
return func(p *providerOptions) {
|
|
p.credentials = credentials
|
|
}
|
|
}
|
|
|
|
// WithOAuth sets the provider client ID & secret options.
|
|
func WithOAuth(clientID, secret string) Option {
|
|
return func(p *providerOptions) {
|
|
p.clientID = clientID
|
|
p.secretID = secret
|
|
}
|
|
}
|
|
|
|
// WithTimeout sets the provider timeout option.
|
|
func WithTimeout(timeout time.Duration) Option {
|
|
return func(p *providerOptions) {
|
|
p.timeout = timeout
|
|
}
|
|
}
|
|
|
|
// WithRegion sets the provider (cloud) region.
|
|
func WithRegion(region string) Option {
|
|
return func(p *providerOptions) {
|
|
p.region = region
|
|
}
|
|
}
|