github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/creds/secretsmanager/manager.go (about) 1 package secretsmanager 2 3 import ( 4 "encoding/json" 5 "errors" 6 7 "code.cloudfoundry.org/lager" 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/credentials" 10 "github.com/aws/aws-sdk-go/aws/session" 11 "github.com/aws/aws-sdk-go/service/secretsmanager" 12 "github.com/pf-qiu/concourse/v6/atc/creds" 13 ) 14 15 const DefaultPipelineSecretTemplate = "/concourse/{{.Team}}/{{.Pipeline}}/{{.Secret}}" 16 const DefaultTeamSecretTemplate = "/concourse/{{.Team}}/{{.Secret}}" 17 18 type Manager struct { 19 AwsAccessKeyID string `long:"access-key" description:"AWS Access key ID"` 20 AwsSecretAccessKey string `long:"secret-key" description:"AWS Secret Access Key"` 21 AwsSessionToken string `long:"session-token" description:"AWS Session Token"` 22 AwsRegion string `long:"region" description:"AWS region to send requests to"` 23 PipelineSecretTemplate string `long:"pipeline-secret-template" description:"AWS Secrets Manager secret identifier template used for pipeline specific parameter" default:"/concourse/{{.Team}}/{{.Pipeline}}/{{.Secret}}"` 24 TeamSecretTemplate string `long:"team-secret-template" description:"AWS Secrets Manager secret identifier template used for team specific parameter" default:"/concourse/{{.Team}}/{{.Secret}}"` 25 SecretManager *SecretsManager 26 } 27 28 func (manager *Manager) Init(log lager.Logger) error { 29 config := &aws.Config{Region: &manager.AwsRegion} 30 if manager.AwsAccessKeyID != "" { 31 config.Credentials = credentials.NewStaticCredentials(manager.AwsAccessKeyID, manager.AwsSecretAccessKey, manager.AwsSessionToken) 32 } 33 34 sess, err := session.NewSession(config) 35 if err != nil { 36 log.Error("create-aws-session", err) 37 return err 38 } 39 40 manager.SecretManager = &SecretsManager{ 41 log: log, 42 api: secretsmanager.New(sess), 43 } 44 return nil 45 } 46 47 func (manager *Manager) Health() (*creds.HealthResponse, error) { 48 health := &creds.HealthResponse{ 49 Method: "GetSecretValue", 50 } 51 52 _, _, _, err := manager.SecretManager.getSecretById("__concourse-health-check") 53 if err != nil { 54 health.Error = err.Error() 55 return health, nil 56 } 57 58 health.Response = map[string]string{ 59 "status": "UP", 60 } 61 62 return health, nil 63 } 64 65 func (manager *Manager) MarshalJSON() ([]byte, error) { 66 health, err := manager.Health() 67 if err != nil { 68 return nil, err 69 } 70 71 return json.Marshal(&map[string]interface{}{ 72 "aws_region": manager.AwsRegion, 73 "pipeline_secret_template": manager.PipelineSecretTemplate, 74 "team_secret_template": manager.TeamSecretTemplate, 75 "health": health, 76 }) 77 } 78 79 func (manager *Manager) IsConfigured() bool { 80 return manager.AwsRegion != "" 81 } 82 83 func (manager *Manager) Validate() error { 84 if _, err := creds.BuildSecretTemplate("pipeline-secret-template", manager.PipelineSecretTemplate); err != nil { 85 return err 86 } 87 if _, err := creds.BuildSecretTemplate("team-secret-template", manager.TeamSecretTemplate); err != nil { 88 return err 89 } 90 91 // All of the AWS credential variables may be empty since credentials may be obtained via environemnt variables 92 // or other means. However, if one of them is provided, then all of them (except session token) must be provided. 93 if manager.AwsAccessKeyID == "" && manager.AwsSecretAccessKey == "" && manager.AwsSessionToken == "" { 94 return nil 95 } 96 97 if manager.AwsAccessKeyID == "" { 98 return errors.New("must provide aws access key id") 99 } 100 101 if manager.AwsSecretAccessKey == "" { 102 return errors.New("must provide aws secret access key") 103 } 104 105 return nil 106 } 107 108 func (manager *Manager) NewSecretsFactory(log lager.Logger) (creds.SecretsFactory, error) { 109 config := &aws.Config{Region: &manager.AwsRegion} 110 if manager.AwsAccessKeyID != "" { 111 config.Credentials = credentials.NewStaticCredentials(manager.AwsAccessKeyID, manager.AwsSecretAccessKey, manager.AwsSessionToken) 112 } 113 114 sess, err := session.NewSession(config) 115 if err != nil { 116 log.Error("create-aws-session", err) 117 return nil, err 118 } 119 120 pipelineSecretTemplate, err := creds.BuildSecretTemplate("pipeline-secret-template", manager.PipelineSecretTemplate) 121 if err != nil { 122 return nil, err 123 } 124 125 teamSecretTemplate, err := creds.BuildSecretTemplate("team-secret-template", manager.TeamSecretTemplate) 126 if err != nil { 127 return nil, err 128 } 129 130 return NewSecretsManagerFactory(log, sess, []*creds.SecretTemplate{pipelineSecretTemplate, teamSecretTemplate}), nil 131 } 132 133 func (manager Manager) Close(logger lager.Logger) { 134 // TODO - to implement 135 }