packer-cn/template/interpolate/aws/secretsmanager/secretsmanager.go

103 lines
2.2 KiB
Go

// Package secretsmanager provide methods to get data from
// AWS Secret Manager
package secretsmanager
import (
"encoding/json"
"errors"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
)
// Client represents an AWS Secrets Manager client
type Client struct {
config *AWSConfig
api secretsmanageriface.SecretsManagerAPI
}
// New creates an AWS Session Manager Client
func New(config *AWSConfig) *Client {
c := &Client{
config: config,
}
s := c.newSession(config)
c.api = secretsmanager.New(s)
return c
}
func (c *Client) newSession(config *AWSConfig) *session.Session {
// Initialize config with error verbosity
sess := aws.NewConfig().WithCredentialsChainVerboseErrors(true)
if config.Region != "" {
sess = sess.WithRegion(config.Region)
}
opts := session.Options{
Config: *sess,
}
return session.Must(session.NewSessionWithOptions(opts))
}
// GetSecret return an AWS Secret Manager secret
// in plain text from a given secret name
func (c *Client) GetSecret(spec *SecretSpec) (string, error) {
params := &secretsmanager.GetSecretValueInput{
SecretId: aws.String(spec.Name),
VersionStage: aws.String("AWSCURRENT"),
}
resp, err := c.api.GetSecretValue(params)
if err != nil {
return "", err
}
if resp.SecretString == nil {
return "", errors.New("Secret is not string")
}
secret := SecretString{
Name: *resp.Name,
SecretString: *resp.SecretString,
}
value, err := getSecretValue(&secret, spec)
if err != nil {
return "", err
}
return value, nil
}
func getSecretValue(s *SecretString, spec *SecretSpec) (string, error) {
var secretValue map[string]string
blob := []byte(s.SecretString)
err := json.Unmarshal(blob, &secretValue)
if err != nil {
return "", err
}
// If key is not set and secret has multiple keys, return error
if spec.Key == "" && len(secretValue) > 1 {
return "", errors.New("Secret has multiple values and no key was set")
}
if spec.Key == "" {
for _, v := range secretValue {
return v, nil
}
}
if v, ok := secretValue[spec.Key]; ok {
return v, nil
}
return "", errors.New("No secret found")
}