From 884bd738215b4fdef11bee5e0b468f282db7fe98 Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Mon, 25 Nov 2019 16:28:33 +0100 Subject: [PATCH 1/8] Loading credentials from env_file parameter --- CHANGELOG.md | 5 +++++ main.go | 11 ++++------- plugin.go | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0575d9c..7cb566f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.2-0.12.11 (2019-11-25) +**BREAKING CHANGE** +* Changed `env-file` param to `env_file` to make it consistent with other parameters +* Added `env_file` param to the plugin config + ## 6.1-0.12.11 (2019-10-18) * Update embedded TF to `0.12.11` diff --git a/main.go b/main.go index 7f230b0..373ac13 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ import ( "os" "github.com/Sirupsen/logrus" - "github.com/joho/godotenv" "github.com/urfave/cli" ) @@ -35,8 +34,9 @@ func main() { EnvVar: "PLUGIN_CA_CERT", }, cli.StringFlag{ - Name: "env-file", - Usage: "source env file", + Name: "env_file", + Usage: "pass filename to source it and load variables into current shell", + EnvVar: "PLUGIN_ENV_FILE", }, cli.StringFlag{ Name: "init_options", @@ -125,10 +125,6 @@ func run(c *cli.Context) error { "Revision": revision, }).Info("Drone Terraform Plugin Version") - if c.String("env-file") != "" { - _ = godotenv.Load(c.String("env-file")) - } - var vars map[string]string if c.String("vars") != "" { if err := json.Unmarshal([]byte(c.String("vars")), &vars); err != nil { @@ -161,6 +157,7 @@ func run(c *cli.Context) error { Parallelism: c.Int("parallelism"), Targets: c.StringSlice("targets"), VarFiles: c.StringSlice("var_files"), + EnvFile: c.String("env_file"), TerraformDataDir: c.String("tf_data_dir"), }, Netrc: Netrc{ diff --git a/plugin.go b/plugin.go index 07dfaa0..6f7a47e 100644 --- a/plugin.go +++ b/plugin.go @@ -16,6 +16,7 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" + "github.com/joho/godotenv" ) type ( @@ -33,6 +34,7 @@ type ( Parallelism int Targets []string VarFiles []string + EnvFile string TerraformDataDir string } @@ -77,6 +79,10 @@ func (p Plugin) Exec() error { } } + if p.Config.EnvFile != "" { + _ = godotenv.Load(p.Config.EnvFile) + } + if p.Config.RoleARN != "" { assumeRole(p.Config.RoleARN) } @@ -169,7 +175,14 @@ func CopyTfEnv() { } } -func assumeRole(roleArn string) { +func assumeRole(roleArn string) bool { + awsTokens := []string{"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"} + for _, token := range awsTokens { + if os.Getenv(token) != "" { + return true + } + } + client := sts.New(session.New()) duration := time.Hour * 1 stsProvider := &stscreds.AssumeRoleProvider{ @@ -188,6 +201,8 @@ func assumeRole(roleArn string) { os.Setenv("AWS_ACCESS_KEY_ID", value.AccessKeyID) os.Setenv("AWS_SECRET_ACCESS_KEY", value.SecretAccessKey) os.Setenv("AWS_SESSION_TOKEN", value.SessionToken) + + return true } func deleteCache(terraformDataDir string) *exec.Cmd { From 7c95d7ef9c72c468166e31016a35ce135b9eb955 Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Tue, 26 Nov 2019 21:49:44 +0100 Subject: [PATCH 2/8] revert CHANGELOG --- CHANGELOG.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb566f..0575d9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,3 @@ -## 6.2-0.12.11 (2019-11-25) -**BREAKING CHANGE** -* Changed `env-file` param to `env_file` to make it consistent with other parameters -* Added `env_file` param to the plugin config - ## 6.1-0.12.11 (2019-10-18) * Update embedded TF to `0.12.11` From 622bc4a0dd8e8db97be962f2c81b9bfcf1ac8b7f Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Tue, 26 Nov 2019 21:52:36 +0100 Subject: [PATCH 3/8] revert godotenv.Load to main.go --- main.go | 6 +++++- plugin.go | 6 ------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index 373ac13..7778723 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "os" "github.com/Sirupsen/logrus" + "github.com/joho/godotenv" "github.com/urfave/cli" ) @@ -125,6 +126,10 @@ func run(c *cli.Context) error { "Revision": revision, }).Info("Drone Terraform Plugin Version") + if c.String("env_file") != "" { + _ = godotenv.Load(c.String("env_file")) + } + var vars map[string]string if c.String("vars") != "" { if err := json.Unmarshal([]byte(c.String("vars")), &vars); err != nil { @@ -157,7 +162,6 @@ func run(c *cli.Context) error { Parallelism: c.Int("parallelism"), Targets: c.StringSlice("targets"), VarFiles: c.StringSlice("var_files"), - EnvFile: c.String("env_file"), TerraformDataDir: c.String("tf_data_dir"), }, Netrc: Netrc{ diff --git a/plugin.go b/plugin.go index 6f7a47e..7a03092 100644 --- a/plugin.go +++ b/plugin.go @@ -16,7 +16,6 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials/stscreds" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" - "github.com/joho/godotenv" ) type ( @@ -34,7 +33,6 @@ type ( Parallelism int Targets []string VarFiles []string - EnvFile string TerraformDataDir string } @@ -79,10 +77,6 @@ func (p Plugin) Exec() error { } } - if p.Config.EnvFile != "" { - _ = godotenv.Load(p.Config.EnvFile) - } - if p.Config.RoleARN != "" { assumeRole(p.Config.RoleARN) } From f47805dbe51208ac7899450587ee8fd0a16f036a Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Tue, 26 Nov 2019 21:54:29 +0100 Subject: [PATCH 4/8] verifying the credentials before assumeRole fn --- plugin.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugin.go b/plugin.go index 7a03092..2e9f356 100644 --- a/plugin.go +++ b/plugin.go @@ -77,7 +77,7 @@ func (p Plugin) Exec() error { } } - if p.Config.RoleARN != "" { + if p.Config.RoleARN != "" && !credsSet() { assumeRole(p.Config.RoleARN) } @@ -169,14 +169,17 @@ func CopyTfEnv() { } } -func assumeRole(roleArn string) bool { +func credsSet() bool { awsTokens := []string{"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"} for _, token := range awsTokens { if os.Getenv(token) != "" { return true } } + return false +} +func assumeRole(roleArn string) { client := sts.New(session.New()) duration := time.Hour * 1 stsProvider := &stscreds.AssumeRoleProvider{ @@ -195,8 +198,6 @@ func assumeRole(roleArn string) bool { os.Setenv("AWS_ACCESS_KEY_ID", value.AccessKeyID) os.Setenv("AWS_SECRET_ACCESS_KEY", value.SecretAccessKey) os.Setenv("AWS_SESSION_TOKEN", value.SessionToken) - - return true } func deleteCache(terraformDataDir string) *exec.Cmd { From e95e85a14e60537b20024e418fdc4f2a77486768 Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Mon, 2 Dec 2019 15:37:35 +0100 Subject: [PATCH 5/8] returning true only when all credentials are set --- plugin.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin.go b/plugin.go index 2e9f356..66a36ca 100644 --- a/plugin.go +++ b/plugin.go @@ -172,11 +172,11 @@ func CopyTfEnv() { func credsSet() bool { awsTokens := []string{"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"} for _, token := range awsTokens { - if os.Getenv(token) != "" { - return true + if os.Getenv(token) == "" { + return false } } - return false + return true } func assumeRole(roleArn string) { From 12857c0fd5a52f4f3cf410571ab9083ba42c7435 Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Mon, 2 Dec 2019 15:38:45 +0100 Subject: [PATCH 6/8] godotenv to v1.3.0 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 516bad3..a551d60 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/franela/goblin v0.0.0-20170111051028-2fa789fd0c6b github.com/go-ini/ini v1.21.1 github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7 - github.com/joho/godotenv v0.0.0-20150907010228-4ed13390c0ac + github.com/joho/godotenv v1.3.0 github.com/urfave/cli v0.0.0-20161006035353-55f715e28c46 golang.org/x/sys v0.0.0-20161006025142-8d1157a43547 ) diff --git a/go.sum b/go.sum index 36769c9..c79449a 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7 h1:SMvOWPJCES github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v0.0.0-20150907010228-4ed13390c0ac h1:wF2VgtpbaLqhBHV9FxVWzgzgv8VcCjZ66Bl/+F6cpT0= github.com/joho/godotenv v0.0.0-20150907010228-4ed13390c0ac/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/urfave/cli v0.0.0-20161006035353-55f715e28c46 h1:EztUvugq7AA7F3lYLmtFQyvKdcY5pisPt10DqPjRCL8= github.com/urfave/cli v0.0.0-20161006035353-55f715e28c46/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= golang.org/x/sys v0.0.0-20161006025142-8d1157a43547/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 3f0744eb5d23576360639bf37470702f192e613a Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Mon, 2 Dec 2019 15:39:22 +0100 Subject: [PATCH 7/8] adding credsSet test --- plugin_test.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/plugin_test.go b/plugin_test.go index a131f11..6a07284 100644 --- a/plugin_test.go +++ b/plugin_test.go @@ -1,13 +1,27 @@ package main import ( + "log" "os" "os/exec" "testing" . "github.com/franela/goblin" + "github.com/joho/godotenv" ) +func loadEnv(keyValue string) { + const FileName = "./.env_example" + env, err := godotenv.Unmarshal(keyValue) + err = godotenv.Write(env, FileName) + if err != nil { + log.Fatal(err) + } + defer os.Remove(FileName) + + _ = godotenv.Load(FileName) +} + func TestPlugin(t *testing.T) { g := Goblin(t) @@ -27,6 +41,63 @@ func TestPlugin(t *testing.T) { }) }) + g.Describe("credsSet", func() { + var awsAccessKeyID string + var awsSecretAccessKey string + var awsSessionToken string + + g.Before(func() { + awsAccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") + awsSecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") + awsSessionToken = os.Getenv("AWS_SESSION_TOKEN") + }) + + // Restoring all credentials after running the credsSet test + g.After(func() { + os.Setenv("AWS_ACCESS_KEY_ID", awsAccessKeyID) + os.Setenv("AWS_SECRET_ACCESS_KEY", awsSecretAccessKey) + os.Setenv("AWS_SESSION_TOKEN", awsSessionToken) + }) + + type args struct { + config string + } + + tests := []struct { + name string + args args + want bool + }{ + { + "Should return true when all credentials were set", + args{config: "AWS_ACCESS_KEY_ID=access_key_id1\nAWS_SECRET_ACCESS_KEY=secret_access_key1\nAWS_SESSION_TOKEN=session_token1"}, + true, + }, + { + "Should return false when access key id is missing", + args{config: "AWS_SECRET_ACCESS_KEY=secret_access_key2\nAWS_SESSION_TOKEN=session_token2"}, + false, + }, + { + "Should return false when secret access key is missing", + args{config: "AWS_ACCESS_KEY_ID=access_key_id3\nAWS_SESSION_TOKEN=session_token3"}, + false, + }, + { + "Should return false when session token is missing", + args{config: "AWS_ACCESS_KEY_ID=access_key_id4\nAWS_SECRET_ACCESS_KEY=secret_access_key4"}, + false, + }, + } + + for _, tt := range tests { + g.It(tt.name, func() { + loadEnv(tt.args.config) + g.Assert(credsSet()).Equal(tt.want) + }) + } + }) + g.Describe("tfApply", func() { g.It("Should return correct apply commands given the arguments", func() { type args struct { From da03b872f1f82a77f84279bf349648499ed05200 Mon Sep 17 00:00:00 2001 From: Neemias Junior Date: Sun, 9 Feb 2020 23:55:31 +0100 Subject: [PATCH 8/8] refactoring plugin_test.go --- plugin_test.go | 49 ++++++++----------------------------------------- 1 file changed, 8 insertions(+), 41 deletions(-) diff --git a/plugin_test.go b/plugin_test.go index 6a07284..23487a9 100644 --- a/plugin_test.go +++ b/plugin_test.go @@ -1,27 +1,13 @@ package main import ( - "log" "os" "os/exec" "testing" . "github.com/franela/goblin" - "github.com/joho/godotenv" ) -func loadEnv(keyValue string) { - const FileName = "./.env_example" - env, err := godotenv.Unmarshal(keyValue) - err = godotenv.Write(env, FileName) - if err != nil { - log.Fatal(err) - } - defer os.Remove(FileName) - - _ = godotenv.Load(FileName) -} - func TestPlugin(t *testing.T) { g := Goblin(t) @@ -42,57 +28,38 @@ func TestPlugin(t *testing.T) { }) g.Describe("credsSet", func() { - var awsAccessKeyID string - var awsSecretAccessKey string - var awsSessionToken string - - g.Before(func() { - awsAccessKeyID = os.Getenv("AWS_ACCESS_KEY_ID") - awsSecretAccessKey = os.Getenv("AWS_SECRET_ACCESS_KEY") - awsSessionToken = os.Getenv("AWS_SESSION_TOKEN") - }) - - // Restoring all credentials after running the credsSet test - g.After(func() { - os.Setenv("AWS_ACCESS_KEY_ID", awsAccessKeyID) - os.Setenv("AWS_SECRET_ACCESS_KEY", awsSecretAccessKey) - os.Setenv("AWS_SESSION_TOKEN", awsSessionToken) - }) - - type args struct { - config string - } - tests := []struct { name string - args args + args map[string]string want bool }{ { "Should return true when all credentials were set", - args{config: "AWS_ACCESS_KEY_ID=access_key_id1\nAWS_SECRET_ACCESS_KEY=secret_access_key1\nAWS_SESSION_TOKEN=session_token1"}, + map[string]string{"AWS_ACCESS_KEY_ID": "x", "AWS_SECRET_ACCESS_KEY": "x", "AWS_SESSION_TOKEN": "x"}, true, }, { "Should return false when access key id is missing", - args{config: "AWS_SECRET_ACCESS_KEY=secret_access_key2\nAWS_SESSION_TOKEN=session_token2"}, + map[string]string{"AWS_SECRET_ACCESS_KEY": "x", "AWS_SESSION_TOKEN": "x"}, false, }, { "Should return false when secret access key is missing", - args{config: "AWS_ACCESS_KEY_ID=access_key_id3\nAWS_SESSION_TOKEN=session_token3"}, + map[string]string{"AWS_ACCESS_KEY_ID": "x", "AWS_SESSION_TOKEN": "x"}, false, }, { "Should return false when session token is missing", - args{config: "AWS_ACCESS_KEY_ID=access_key_id4\nAWS_SECRET_ACCESS_KEY=secret_access_key4"}, + map[string]string{"AWS_ACCESS_KEY_ID": "x", "AWS_SECRET_ACCESS_KEY": "x"}, false, }, } for _, tt := range tests { g.It(tt.name, func() { - loadEnv(tt.args.config) + for k, v := range tt.args { + os.Setenv(k, v) + } g.Assert(credsSet()).Equal(tt.want) }) }