123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- package env
- import (
- "context"
- "fmt"
- "os"
- "strings"
- "time"
- "github.com/aws/aws-sdk-go-v2/aws"
- awsConfig "github.com/aws/aws-sdk-go-v2/config"
- "github.com/aws/aws-sdk-go-v2/service/secretsmanager"
- "github.com/aws/aws-sdk-go-v2/service/ssm"
- )
- const (
- // defaultAWSRegion represents default AWS region for all configuration
- defaultAWSRegion = "us-west-1"
- )
- var (
- IMGPROXY_ENV_AWS_SECRET_ID = Describe("IMGPROXY_ENV_AWS_SECRET_ID", "string")
- IMGPROXY_ENV_AWS_SECRET_VERSION_ID = Describe("IMGPROXY_ENV_AWS_SECRET_VERSION_ID", "string")
- IMGPROXY_ENV_AWS_SECRET_VERSION_STAGE = Describe("IMGPROXY_ENV_AWS_SECRET_VERSION_STAGE", "string")
- IMGPROXY_ENV_AWS_SECRET_REGION = Describe("IMGPROXY_ENV_AWS_SECRET_REGION", "AWS region ("+defaultAWSRegion+")")
- IMGPROXY_ENV_AWS_SSM_PARAMETERS_PATH = Describe("IMGPROXY_ENV_AWS_SSM_PARAMETERS_PATH", "string")
- IMGPROXY_ENV_AWS_SSM_PARAMETERS_REGION = Describe("IMGPROXY_ENV_AWS_SSM_PARAMETERS_REGION", "AWS region ("+defaultAWSRegion+")")
- )
- func loadAWSSecret(ctx context.Context) error {
- var secretID, secretVersionID, secretVersionStage, secretRegion string
- String(&secretID, IMGPROXY_ENV_AWS_SECRET_ID)
- String(&secretVersionID, IMGPROXY_ENV_AWS_SECRET_VERSION_ID)
- String(&secretVersionStage, IMGPROXY_ENV_AWS_SECRET_VERSION_STAGE)
- String(&secretRegion, IMGPROXY_ENV_AWS_SECRET_REGION)
- // No secret ID, no aws
- if len(secretID) == 0 {
- return nil
- }
- // Let's form AWS default config
- conf, err := awsConfig.LoadDefaultConfig(ctx)
- if err != nil {
- return fmt.Errorf("can't load AWS Secrets Manager config: %s", err)
- }
- if len(secretRegion) > 0 {
- conf.Region = secretRegion
- }
- if len(conf.Region) == 0 {
- conf.Region = defaultAWSRegion
- }
- // Let's create secrets manager client
- client := secretsmanager.NewFromConfig(conf)
- input := secretsmanager.GetSecretValueInput{SecretId: aws.String(secretID)}
- if len(secretVersionID) > 0 {
- input.VersionId = aws.String(secretVersionID)
- } else if len(secretVersionStage) > 0 {
- input.VersionStage = aws.String(secretVersionStage)
- }
- ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
- defer cancel()
- output, err := client.GetSecretValue(ctx, &input)
- if err != nil {
- return fmt.Errorf("can't retrieve config from AWS Secrets Manager: %s", err)
- }
- // No secret string, failed to initialize secrets manager, return
- if output.SecretString == nil {
- return nil
- }
- return unmarshalEnv(*output.SecretString, "AWS Secrets Manager")
- }
- // loadAWSSystemManagerParams loads environment variables from AWS System Manager
- func loadAWSSystemManagerParams(ctx context.Context) error {
- var paramsPath, paramsRegion string
- String(¶msPath, IMGPROXY_ENV_AWS_SSM_PARAMETERS_PATH)
- String(¶msRegion, IMGPROXY_ENV_AWS_SSM_PARAMETERS_REGION)
- // Path is not set: can't use SSM
- if len(paramsPath) == 0 {
- return nil
- }
- conf, err := awsConfig.LoadDefaultConfig(ctx)
- if err != nil {
- return fmt.Errorf("can't load AWS SSM config: %s", err)
- }
- conf.Region = defaultAWSRegion
- if len(paramsRegion) != 0 {
- conf.Region = paramsRegion
- }
- // Let's create SSM client
- client := ssm.NewFromConfig(conf)
- ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
- defer cancel()
- var nextToken *string
- for {
- input := ssm.GetParametersByPathInput{
- Path: aws.String(paramsPath),
- WithDecryption: aws.Bool(true),
- NextToken: nextToken,
- }
- output, err := client.GetParametersByPath(ctx, &input)
- if err != nil {
- return fmt.Errorf("can't retrieve parameters from AWS SSM: %s", err)
- }
- for _, p := range output.Parameters {
- if p.Name == nil || p.Value == nil {
- continue
- }
- if p.DataType == nil || *p.DataType != "text" {
- continue
- }
- name := *p.Name
- env := strings.ReplaceAll(
- strings.TrimPrefix(strings.TrimPrefix(name, paramsPath), "/"),
- "/", "_",
- )
- if err = os.Setenv(env, *p.Value); err != nil {
- return fmt.Errorf("can't set %s env variable from AWS SSM: %s", env, err)
- }
- }
- if nextToken = output.NextToken; nextToken == nil {
- break
- }
- }
- return nil
- }
|