Skip to content

Commit

Permalink
feat: env variables/flags available again for single provider configu…
Browse files Browse the repository at this point in the history
…ration
  • Loading branch information
hbollon committed Jun 24, 2021
1 parent e28539d commit 694ef54
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 86 deletions.
36 changes: 33 additions & 3 deletions config/config.go
Expand Up @@ -119,14 +119,44 @@ func (c *Config) LoadConfigFromYaml() *Config {
return c
}

// LoadConfig loads the config from flags & environment
func LoadConfig(version string) *Config {
// Initialize Config with one obj per providers arrays
// to allow usage of flags / env variables on single provider configuration
func initDefaultConfig() Config {
var c Config
parser := flags.NewParser(&c, flags.Default)
var awsInitialConfig AWSConfig
var tfeInitialConfig TFEConfig
var gcpInitialConfig GCPConfig
var gitlabInitialConfig GitlabConfig

parseStructFlagsAndEnv(&awsInitialConfig)
c.AWS = append(c.AWS, awsInitialConfig)

parseStructFlagsAndEnv(&tfeInitialConfig)
c.TFE = append(c.TFE, tfeInitialConfig)

parseStructFlagsAndEnv(&gcpInitialConfig)
c.GCP = append(c.GCP, gcpInitialConfig)

parseStructFlagsAndEnv(&gitlabInitialConfig)
c.Gitlab = append(c.Gitlab, gitlabInitialConfig)

return c
}

// Parse flags and env variables to given struct using go-flags
// parser
func parseStructFlagsAndEnv(obj interface{}) {
parser := flags.NewParser(obj, flags.Default)
if _, err := parser.Parse(); err != nil {
fmt.Printf("Failed to parse flags: %s", err)
os.Exit(1)
}
}

// LoadConfig loads the config from flags & environment
func LoadConfig(version string) *Config {
c := initDefaultConfig()
parseStructFlagsAndEnv(&c)

if c.ConfigFilePath != "" {
if _, err := os.Stat(c.ConfigFilePath); err == nil {
Expand Down
62 changes: 32 additions & 30 deletions state/aws.go
Expand Up @@ -34,38 +34,40 @@ type AWS struct {
func NewAWS(c *config.Config) []*AWS {
var awsInstances []*AWS
for _, aws := range c.AWS {
sess := session.Must(session.NewSession())
awsConfig := aws_sdk.NewConfig()
if len(aws.APPRoleArn) > 0 {
log.Debugf("Using %s role", aws.APPRoleArn)
creds := stscreds.NewCredentials(sess, aws.APPRoleArn, func(p *stscreds.AssumeRoleProvider) {
if aws.ExternalID != "" {
p.ExternalID = aws_sdk.String(aws.ExternalID)
}
})
awsConfig.WithCredentials(creds)
}
if aws.S3.Bucket != "" {
sess := session.Must(session.NewSession())
awsConfig := aws_sdk.NewConfig()
if len(aws.APPRoleArn) > 0 {
log.Debugf("Using %s role", aws.APPRoleArn)
creds := stscreds.NewCredentials(sess, aws.APPRoleArn, func(p *stscreds.AssumeRoleProvider) {
if aws.ExternalID != "" {
p.ExternalID = aws_sdk.String(aws.ExternalID)
}
})
awsConfig.WithCredentials(creds)
}

if e := aws.Endpoint; e != "" {
awsConfig.WithEndpoint(e)
}
if e := aws.Region; e != "" {
awsConfig.WithRegion(e)
}
awsConfig.S3ForcePathStyle = &aws.S3.ForcePathStyle

instance := &AWS{
svc: s3.New(sess, awsConfig),
bucket: aws.S3.Bucket,
keyPrefix: aws.S3.KeyPrefix,
fileExtension: aws.S3.FileExtension,
dynamoSvc: dynamodb.New(sess, awsConfig),
dynamoTable: aws.DynamoDBTable,
noLocks: c.Provider.NoLocks,
noVersioning: c.Provider.NoVersioning,
if e := aws.Endpoint; e != "" {
awsConfig.WithEndpoint(e)
}
if e := aws.Region; e != "" {
awsConfig.WithRegion(e)
}
awsConfig.S3ForcePathStyle = &aws.S3.ForcePathStyle

instance := &AWS{
svc: s3.New(sess, awsConfig),
bucket: aws.S3.Bucket,
keyPrefix: aws.S3.KeyPrefix,
fileExtension: aws.S3.FileExtension,
dynamoSvc: dynamodb.New(sess, awsConfig),
dynamoTable: aws.DynamoDBTable,
noLocks: c.Provider.NoLocks,
noVersioning: c.Provider.NoVersioning,
}
log.Debugf("Instance: %+v\n", *instance)
awsInstances = append(awsInstances, instance)
}
log.Debugf("Instance: %+v\n", *instance)
awsInstances = append(awsInstances, instance)
}

return awsInstances
Expand Down
44 changes: 23 additions & 21 deletions state/gcp.go
Expand Up @@ -31,30 +31,32 @@ func NewGCP(c *config.Config) ([]*GCP, error) {
var gcpInstances []*GCP
var err error
for _, gcp := range c.GCP {
if gcp.GCPSAKey != "" {
log.WithFields(log.Fields{
"path": gcp.GCPSAKey,
}).Info("Authenticating using service account key")
opt := option.WithCredentialsFile(gcp.GCPSAKey)
client, err = storage.NewClient(ctx, opt) // Use service account key
} else {
client, err = storage.NewClient(ctx) // Use base credentials
}
if gcp.GCSBuckets != nil {
if gcp.GCPSAKey != "" {
log.WithFields(log.Fields{
"path": gcp.GCPSAKey,
}).Info("Authenticating using service account key")
opt := option.WithCredentialsFile(gcp.GCPSAKey)
client, err = storage.NewClient(ctx, opt) // Use service account key
} else {
client, err = storage.NewClient(ctx) // Use base credentials
}

if err != nil {
log.Fatalf("Failed to create client: %v", err)
return nil, err
}
if err != nil {
log.Fatalf("Failed to create client: %v", err)
return nil, err
}

instance := &GCP{
svc: client,
buckets: gcp.GCSBuckets,
}
gcpInstances = append(gcpInstances, instance)
instance := &GCP{
svc: client,
buckets: gcp.GCSBuckets,
}
gcpInstances = append(gcpInstances, instance)

log.WithFields(log.Fields{
"buckets": gcp.GCSBuckets,
}).Info("Client successfully created")
log.WithFields(log.Fields{
"buckets": gcp.GCSBuckets,
}).Info("Client successfully created")
}
}

return gcpInstances, nil
Expand Down
8 changes: 5 additions & 3 deletions state/gitlab.go
Expand Up @@ -21,10 +21,12 @@ type Gitlab struct {
func NewGitlab(c *config.Config) []*Gitlab {
var gitlabInstances []*Gitlab
for _, gl := range c.Gitlab {
instance := &Gitlab{
Client: gitlab.NewClient(gl.Address, gl.Token),
if gl.Token != "" {
instance := &Gitlab{
Client: gitlab.NewClient(gl.Address, gl.Token),
}
gitlabInstances = append(gitlabInstances, instance)
}
gitlabInstances = append(gitlabInstances, instance)
}
return gitlabInstances
}
Expand Down
37 changes: 22 additions & 15 deletions state/state.go
Expand Up @@ -41,45 +41,52 @@ type Provider interface {

// Configure the state provider
func Configure(c *config.Config) ([]Provider, error) {
log.Infof("%+v\n", *c)
var providers []Provider
if len(c.TFE) > 0 {
log.Info("Using Terraform Enterprise as state/locks provider")
objs, err := NewTFE(c)
if err != nil {
return []Provider{}, err
}
for _, tfeObj := range objs {
providers = append(providers, tfeObj)
if len(objs) > 0 {
log.Info("Using Terraform Enterprise as state/locks provider")
for _, tfeObj := range objs {
providers = append(providers, tfeObj)
}
}
}

if len(c.GCP) > 0 {
log.Info("Using Google Cloud as state/locks provider")
objs, err := NewGCP(c)
if err != nil {
return []Provider{}, err
}
for _, gcpObj := range objs {
providers = append(providers, gcpObj)
if len(objs) > 0 {
log.Info("Using Google Cloud as state/locks provider")
for _, gcpObj := range objs {
providers = append(providers, gcpObj)
}
}
}

if len(c.Gitlab) > 0 {
log.Info("Using Gitab as state/locks provider")
for _, glObj := range NewGitlab(c) {
providers = append(providers, glObj)
objs := NewGitlab(c)
if len(objs) > 0 {
log.Info("Using Gitab as state/locks provider")
for _, glObj := range objs {
providers = append(providers, glObj)
}
}
}

if len(c.AWS) > 0 {
log.Info("Using AWS (S3+DynamoDB) as state/locks provider")
for _, awsObj := range NewAWS(c) {
log.Infof("AWS: %+v\n", *awsObj)
providers = append(providers, awsObj)
objs := NewAWS(c)
if len(objs) > 0 {
log.Info("Using AWS (S3+DynamoDB) as state/locks provider")
for _, awsObj := range objs {
providers = append(providers, awsObj)
}
}
}

log.Infof("%+v\n", providers)
return providers, nil
}
30 changes: 16 additions & 14 deletions state/tfe.go
Expand Up @@ -22,23 +22,25 @@ type TFE struct {
func NewTFE(c *config.Config) ([]*TFE, error) {
var tfeInstances []*TFE
for _, tfeObj := range c.TFE {
config := &tfe.Config{
Address: tfeObj.Address,
Token: tfeObj.Token,
}
if tfeObj.Token != "" {
config := &tfe.Config{
Address: tfeObj.Address,
Token: tfeObj.Token,
}

client, err := tfe.NewClient(config)
if err != nil {
return nil, err
}
client, err := tfe.NewClient(config)
if err != nil {
return nil, err
}

ctx := context.Background()
instance := &TFE{
Client: client,
org: tfeObj.Organization,
ctx: &ctx,
ctx := context.Background()
instance := &TFE{
Client: client,
org: tfeObj.Organization,
ctx: &ctx,
}
tfeInstances = append(tfeInstances, instance)
}
tfeInstances = append(tfeInstances, instance)
}

return tfeInstances, nil
Expand Down
21 changes: 21 additions & 0 deletions test/docker-compose.yml
Expand Up @@ -28,6 +28,27 @@ services:
ports:
- "8080:8080"

# terraboard-dev-multi-providers:
# build:
# context: ../
# dockerfile: ./Dockerfile
# environment:
# AWS_ACCESS_KEY_ID: root
# AWS_SECRET_ACCESS_KEY: mypassword
# DB_SSLMODE: disable
# CONFIG_FILE: config/config.yml
# GODEBUG: netdns=go
# depends_on:
# db:
# condition: service_healthy
# minio:
# condition: service_started
# volumes:
# - ../static:/static:ro
# - ./config.yml:/config/config.yml:ro
# ports:
# - "8081:8081"

minio:
image: minio/minio:latest
environment:
Expand Down

0 comments on commit 694ef54

Please sign in to comment.