From bf5487081b21edb02e9fde7bd4608e775daa40bd Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Mon, 22 Jun 2020 17:22:43 -0700 Subject: [PATCH 1/8] Refactoring and integration work on apply command Stream apply output Changed apply test to compare a file rather than output Changed prompts to use til for appending env Added handling for relative paths during execution Append env from outside zero when running commands inside Changed to execute makefile in module dir, not project dir --- cmd/apply.go | 11 ++- go.mod | 3 +- go.sum | 4 ++ internal/apply/apply.go | 72 +++++++++---------- internal/apply/apply_test.go | 32 ++++++--- internal/init/prompts.go | 12 +--- internal/module/module.go | 6 +- internal/module/module_internal_test.go | 4 +- internal/util/util.go | 21 ++++-- tests/test_data/apply/project1/Makefile | 2 + tests/test_data/apply/project2/Makefile | 2 + tests/test_data/apply/zero-project.yml | 19 +++++ .../zero-aws-eks-stack/Makefile | 2 - .../zero-deployable-backend/Makefile | 2 - .../zero-deployable-react-frontend/Makefile | 2 - .../test_data/sample_project/zero-project.yml | 17 ----- 16 files changed, 118 insertions(+), 93 deletions(-) create mode 100644 tests/test_data/apply/project1/Makefile create mode 100644 tests/test_data/apply/project2/Makefile create mode 100644 tests/test_data/apply/zero-project.yml delete mode 100644 tests/test_data/sample_project/zero-aws-eks-stack/Makefile delete mode 100644 tests/test_data/sample_project/zero-deployable-backend/Makefile delete mode 100644 tests/test_data/sample_project/zero-deployable-react-frontend/Makefile delete mode 100644 tests/test_data/sample_project/zero-project.yml diff --git a/cmd/apply.go b/cmd/apply.go index 434eb0f00..32d86ec48 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -1,6 +1,9 @@ package cmd import ( + "log" + "os" + "github.com/commitdev/zero/internal/apply" "github.com/commitdev/zero/internal/config/projectconfig" "github.com/commitdev/zero/internal/constants" @@ -21,7 +24,11 @@ var applyCmd = &cobra.Command{ Use: "apply", Short: "Execute modules to create projects, infrastructure, etc.", Run: func(cmd *cobra.Command, args []string) { - // @TODO rootdir? - apply.Apply(projectconfig.RootDir, applyConfigPath, applyEnvironments) + rootDir, err := os.Getwd() + if err != nil { + log.Println(err) + rootDir = projectconfig.RootDir + } + apply.Apply(rootDir, applyConfigPath, applyEnvironments) }, } diff --git a/go.mod b/go.mod index 1de9fc874..1beeb1a62 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/commitdev/zero -go 1.12 +go 1.13 require ( github.com/aws/aws-sdk-go v1.25.33 @@ -24,6 +24,7 @@ require ( github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/spf13/cobra v0.0.6 github.com/stretchr/testify v1.4.0 + github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect diff --git a/go.sum b/go.sum index d3dcfc63e..6106a2703 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -142,6 +143,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/moby v1.13.1 h1:mC5WwQwCXt/dYxZ1cIrRsnJAWw7VdtcTZUIGr4tXzOM= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -179,6 +181,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae h1:vgGSvdW5Lqg+I1aZOlG32uyE6xHpLdKhZzcTEktz5wM= +github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae/go.mod h1:quDq6Se6jlGwiIKia/itDZxqC5rj6/8OdFyMMAwTxCs= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= diff --git a/internal/apply/apply.go b/internal/apply/apply.go index 92e82ce0c..e14b6e405 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -2,25 +2,39 @@ package apply import ( "fmt" + "path/filepath" "log" "os/exec" "path" "strings" + "github.com/commitdev/zero/internal/module" "github.com/commitdev/zero/internal/util" - "github.com/commitdev/zero/pkg/util/flog" "github.com/commitdev/zero/internal/config/projectconfig" "github.com/commitdev/zero/pkg/util/exit" + "github.com/commitdev/zero/pkg/util/flog" "github.com/manifoldco/promptui" ) -// Apply will bootstrap the runtime environment for the project -func Apply(dir string, applyConfigPath string, applyEnvironments []string) []string { - context := loadContext(dir, applyConfigPath, applyEnvironments) +func Apply(rootDir string, configPath string, environments []string) { + if strings.Trim(configPath, " ") == "" { + exit.Fatal("config path cannot be empty!") + } + configFilePath := path.Join(rootDir, configPath) + projectConfig := projectconfig.LoadConfig(configFilePath) - flog.Infof(":tada: Bootstrapping project %s. Please use the zero.[hcl, yaml] file to modify the project as needed. %s.", context.Name) + if len(environments) == 0 { + fmt.Println(`Choose the environments to apply. This will create infrastructure, CI pipelines, etc. +At this point, real things will be generated that may cost money! +Only a single environment may be suitable for an initial test, but for a real system we suggest setting up both staging and production environments.`) + environments = promptEnvironments() + } + + validateEnvironments(environments) + + flog.Infof(":tada: Bootstrapping project %s. Please use the zero.yml file to modify the project as needed.", projectConfig.Name) flog.Infof("Cloud provider: %s", "AWS") // will this come from the config? @@ -28,28 +42,29 @@ func Apply(dir string, applyConfigPath string, applyEnvironments []string) []str flog.Infof("Infrastructure executor: %s", "Terraform") - // other details... + applyAll(rootDir, *projectConfig, environments) - return makeAll(dir, context, applyEnvironments) + // TODO Summary + flog.Infof(":check_mark_button: Done - Summary goes here.") } -// loadContext will load the context/configuration to be used by the apply command -func loadContext(dir string, applyConfigPath string, applyEnvironments []string) *projectconfig.ZeroProjectConfig { - if len(applyEnvironments) == 0 { - fmt.Println(`Choose the environments to apply. This will create infrastructure, CI pipelines, etc. -At this point, real things will be generated that may cost money! -Only a single environment may be suitable for an initial test, but for a real system we suggest setting up both staging and production environments.`) - applyEnvironments = promptEnvironments() - } +func applyAll(dir string, projectConfig projectconfig.ZeroProjectConfig, applyEnvironments []string) { + environmentArg := fmt.Sprintf("ENVIRONMENT=%s", strings.Join(applyEnvironments, ",")) - validateEnvironments(applyEnvironments) + for _, mod := range projectConfig.Modules { + dirArg := fmt.Sprintf("PROJECT_DIR=%s", path.Join(dir, mod.Files.Directory)) + envList := []string{environmentArg, dirArg} - if applyConfigPath == "" { - exit.Fatal("config path cannot be empty!") + modulePath := module.GetSourceDir(mod.Files.Source) + // Passed in `dir` will only be used to find the project path, not the module path, + // unless the module path is relative + if module.IsLocal(mod.Files.Source) && !filepath.IsAbs(modulePath) { + modulePath = filepath.Join(dir, modulePath) + } + + envList = util.AppendProjectEnvToCmdEnv(mod.Parameters, envList) + util.ExecuteCommand(exec.Command("make"), modulePath, envList) } - configPath := path.Join(dir, applyConfigPath) - projectConfig := projectconfig.LoadConfig(configPath) - return projectConfig } // promptEnvironments Prompts the user for the environments to apply against and returns a slice of strings representing the environments @@ -85,18 +100,3 @@ func validateEnvironments(applyEnvironments []string) { } } } - -func makeAll(dir string, projectContext *projectconfig.ZeroProjectConfig, applyEnvironments []string) []string { - environmentArg := fmt.Sprintf("ENVIRONMENT=%s", strings.Join(applyEnvironments, ",")) - envList := []string{environmentArg} - outputs := []string{} - - for _, mod := range projectContext.Modules { - modulePath := path.Join(dir, mod.Files.Directory) - envList = util.AppendProjectEnvToCmdEnv(mod.Parameters, envList) - - output := util.ExecuteCommandOutput(exec.Command("make"), modulePath, envList) - outputs = append(outputs, output) - } - return outputs -} diff --git a/internal/apply/apply_test.go b/internal/apply/apply_test.go index 4a81c628f..7f83f9dce 100644 --- a/internal/apply/apply_test.go +++ b/internal/apply/apply_test.go @@ -1,27 +1,41 @@ package apply_test import ( + "io/ioutil" + "os" + "path/filepath" "testing" "github.com/commitdev/zero/internal/apply" "github.com/commitdev/zero/internal/constants" "github.com/stretchr/testify/assert" + "github.com/termie/go-shutil" ) func TestApply(t *testing.T) { - // @TODO is there a way to do this without relative paths? - dir := "../../tests/test_data/sample_project/" + dir := "../../tests/test_data/apply/" applyConfigPath := constants.ZeroProjectYml applyEnvironments := []string{"staging", "production"} - want := []string{ - "make module zero-aws-eks-stack\n", - "make module zero-deployable-backend\n", - "make module zero-deployable-react-frontend\n", - } + tmpDir := filepath.Join(os.TempDir(), "apply") + + err := os.RemoveAll(tmpDir) + assert.NoError(t, err) + + err = shutil.CopyTree(dir, tmpDir, nil) + assert.NoError(t, err) t.Run("Should run apply and execute make on each folder module", func(t *testing.T) { - got := apply.Apply(dir, applyConfigPath, applyEnvironments) - assert.ElementsMatch(t, want, got) + apply.Apply(tmpDir, applyConfigPath, applyEnvironments) + assert.FileExists(t, filepath.Join(tmpDir, "project1/project.out")) + assert.FileExists(t, filepath.Join(tmpDir, "project2/project.out")) + + content, err := ioutil.ReadFile(filepath.Join(tmpDir, "project1/project.out")) + assert.NoError(t, err) + assert.Equal(t, string(content), "foo: bar\n") + + content, err = ioutil.ReadFile(filepath.Join(tmpDir, "project2/project.out")) + assert.NoError(t, err) + assert.Equal(t, string(content), "baz: qux\n") }) } diff --git a/internal/init/prompts.go b/internal/init/prompts.go index 1a46b7cbe..d31ab9648 100644 --- a/internal/init/prompts.go +++ b/internal/init/prompts.go @@ -10,6 +10,7 @@ import ( "github.com/commitdev/zero/internal/config/globalconfig" "github.com/commitdev/zero/internal/config/moduleconfig" + "github.com/commitdev/zero/internal/util" "github.com/commitdev/zero/pkg/credentials" "github.com/commitdev/zero/pkg/util/exit" "github.com/manifoldco/promptui" @@ -127,7 +128,7 @@ func promptParameter(prompt PromptHandler) (error, string) { func executeCmd(command string, envVars map[string]string) string { cmd := exec.Command("bash", "-c", command) - cmd.Env = appendProjectEnvToCmdEnv(envVars, os.Environ()) + cmd.Env = util.AppendProjectEnvToCmdEnv(envVars, os.Environ()) out, err := cmd.Output() if err != nil { @@ -142,15 +143,6 @@ func sanitizeParameterValue(str string) string { return re.ReplaceAllString(str, "") } -func appendProjectEnvToCmdEnv(envMap map[string]string, envList []string) []string { - for key, val := range envMap { - if val != "" { - envList = append(envList, fmt.Sprintf("%s=%s", key, val)) - } - } - return envList -} - // PromptParams renders series of prompt UI based on the config func PromptModuleParams(moduleConfig moduleconfig.ModuleConfig, parameters map[string]string) (map[string]string, error) { diff --git a/internal/module/module.go b/internal/module/module.go index d8a17e225..8e8fd5322 100644 --- a/internal/module/module.go +++ b/internal/module/module.go @@ -21,7 +21,7 @@ func FetchModule(source string, wg *sync.WaitGroup) { defer wg.Done() localPath := GetSourceDir(source) - if !isLocal(source) { + if !IsLocal(source) { err := getter.Get(localPath, source) if err != nil { exit.Fatal("Failed to fetch remote module from %s: %v\n", source, err) @@ -41,7 +41,7 @@ func ParseModuleConfig(source string) (moduleconfig.ModuleConfig, error) { // GetSourcePath gets a unique local source directory name. For local modules, it use the local directory func GetSourceDir(source string) string { - if !isLocal(source) { + if !IsLocal(source) { h := md5.New() io.WriteString(h, source) source = base64.StdEncoding.EncodeToString(h.Sum(nil)) @@ -52,7 +52,7 @@ func GetSourceDir(source string) string { } // IsLocal uses the go-getter FileDetector to check if source is a file -func isLocal(source string) bool { +func IsLocal(source string) bool { pwd := util.GetCwd() // ref: https://github.com/hashicorp/go-getter/blob/master/detect_test.go diff --git a/internal/module/module_internal_test.go b/internal/module/module_internal_test.go index 8ec9e0826..e191da406 100644 --- a/internal/module/module_internal_test.go +++ b/internal/module/module_internal_test.go @@ -6,13 +6,13 @@ import ( func TestIsLocal(t *testing.T) { source := "./tests/test_data/modules" - res := isLocal(source) + res := IsLocal(source) if !res { t.Errorf("Error, source %s SHOULD BE determined as local", source) } source = "https://github.com/commitdev/my-repo" - res = isLocal(source) + res = IsLocal(source) if res { t.Errorf("Error, source %s SHOULD NOT BE determined as local", source) } diff --git a/internal/util/util.go b/internal/util/util.go index cb754bdff..b427c1858 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -9,6 +9,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "strings" "text/template" @@ -46,9 +47,12 @@ func GetCwd() string { } func ExecuteCommand(cmd *exec.Cmd, pathPrefix string, envars []string) { - dir := GetCwd() - cmd.Dir = path.Join(dir, pathPrefix) + cmd.Dir = pathPrefix + if !filepath.IsAbs(pathPrefix) { + dir := GetCwd() + cmd.Dir = path.Join(dir, pathPrefix) + } stdoutPipe, _ := cmd.StdoutPipe() stderrPipe, _ := cmd.StderrPipe() @@ -56,7 +60,7 @@ func ExecuteCommand(cmd *exec.Cmd, pathPrefix string, envars []string) { var errStdout, errStderr error if envars != nil { - cmd.Env = envars + cmd.Env = append(os.Environ(), envars...) } err := cmd.Start() @@ -88,17 +92,20 @@ func ExecuteCommand(cmd *exec.Cmd, pathPrefix string, envars []string) { // ExecuteCommandOutput runs the command and returns its // combined standard output and standard error. func ExecuteCommandOutput(cmd *exec.Cmd, pathPrefix string, envars []string) string { - dir := GetCwd() - cmd.Dir = path.Join(dir, pathPrefix) + cmd.Dir = pathPrefix + if !filepath.IsAbs(pathPrefix) { + dir := GetCwd() + cmd.Dir = path.Join(dir, pathPrefix) + } if envars != nil { - cmd.Env = envars + cmd.Env = append(os.Environ(), envars...) } out, err := cmd.CombinedOutput() if err != nil { - log.Fatalf("Executing command failed: (%v) %s\n", err, out) + log.Fatalf("Executing command with output failed: (%v) %s\n", err, out) } return string(out) } diff --git a/tests/test_data/apply/project1/Makefile b/tests/test_data/apply/project1/Makefile new file mode 100644 index 000000000..3df071059 --- /dev/null +++ b/tests/test_data/apply/project1/Makefile @@ -0,0 +1,2 @@ +current_dir: + @echo "foo: ${foo}" > project.out diff --git a/tests/test_data/apply/project2/Makefile b/tests/test_data/apply/project2/Makefile new file mode 100644 index 000000000..a17340f10 --- /dev/null +++ b/tests/test_data/apply/project2/Makefile @@ -0,0 +1,2 @@ +current_dir: + @echo "baz: ${baz}" > project.out diff --git a/tests/test_data/apply/zero-project.yml b/tests/test_data/apply/zero-project.yml new file mode 100644 index 000000000..114ca1c99 --- /dev/null +++ b/tests/test_data/apply/zero-project.yml @@ -0,0 +1,19 @@ +name: sample_project + +context: + +modules: + project1: + parameters: + foo: bar + files: + dir: project1 + repo: github.com/commitdev/project1 + source: project1 + project2: + parameters: + baz: qux + files: + dir: project2 + repo: github.com/commitdev/project2 + source: project2 diff --git a/tests/test_data/sample_project/zero-aws-eks-stack/Makefile b/tests/test_data/sample_project/zero-aws-eks-stack/Makefile deleted file mode 100644 index 105cbca1b..000000000 --- a/tests/test_data/sample_project/zero-aws-eks-stack/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -current_dir: - @echo "make module" `pwd | xargs basename` \ No newline at end of file diff --git a/tests/test_data/sample_project/zero-deployable-backend/Makefile b/tests/test_data/sample_project/zero-deployable-backend/Makefile deleted file mode 100644 index 105cbca1b..000000000 --- a/tests/test_data/sample_project/zero-deployable-backend/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -current_dir: - @echo "make module" `pwd | xargs basename` \ No newline at end of file diff --git a/tests/test_data/sample_project/zero-deployable-react-frontend/Makefile b/tests/test_data/sample_project/zero-deployable-react-frontend/Makefile deleted file mode 100644 index 105cbca1b..000000000 --- a/tests/test_data/sample_project/zero-deployable-react-frontend/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -current_dir: - @echo "make module" `pwd | xargs basename` \ No newline at end of file diff --git a/tests/test_data/sample_project/zero-project.yml b/tests/test_data/sample_project/zero-project.yml deleted file mode 100644 index e8731b2fe..000000000 --- a/tests/test_data/sample_project/zero-project.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: sample_project - -context: - -modules: - aws-eks-stack: - files: - dir: zero-aws-eks-stack - repo: github.com/commitdev/zero-aws-eks-stack - deployable-backend: - files: - dir: zero-deployable-backend - repo: github.com/commitdev/zero-deployable-backend - deployable-react-frontend: - files: - dir: zero-deployable-react-frontend - repo: github.com/commitdev/zero-deployable-react-frontend \ No newline at end of file From de92b7ef99bc98b5a1ff2b634c120b2f9018d480 Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Tue, 23 Jun 2020 11:06:48 -0700 Subject: [PATCH 2/8] Added code to get env vars from project credentials struct --- cmd/apply_test.go | 11 ------ cmd/init_test.go | 30 --------------- internal/apply/apply.go | 11 +++++- internal/apply/apply_test.go | 4 +- internal/config/globalconfig/global_config.go | 38 +++++++++++++++++-- .../config/globalconfig/global_config_test.go | 29 +++++++++++--- internal/init/init.go | 2 +- tests/test_data/apply/project1/Makefile | 1 + 8 files changed, 71 insertions(+), 55 deletions(-) delete mode 100644 cmd/apply_test.go delete mode 100644 cmd/init_test.go diff --git a/cmd/apply_test.go b/cmd/apply_test.go deleted file mode 100644 index d72b42cc4..000000000 --- a/cmd/apply_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package cmd_test - -import ( - "testing" -) - -func TestApply(t *testing.T) { - // if false { - // t.Fatalf("apply failed!") - // } -} diff --git a/cmd/init_test.go b/cmd/init_test.go deleted file mode 100644 index dfde5e131..000000000 --- a/cmd/init_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package cmd_test - -import ( - "testing" -) - -func TestInitWorks(t *testing.T) { - // @TODO : Figure out a way to test this - // tmpdir, err := ioutil.TempDir("", "commit0-") - // if err != nil { - // t.Fatal(err) - // } - - // projectName := "test-project" - - // templates := packr.New("templates", "../templates") - // templator := templator.NewTemplator(templates) - - // root := cmd.Create(projectName, tmpdir, templator) - // defer os.RemoveAll(tmpdir) - - // st, err := os.Stat(path.Join(root, util.CommitYml)) - // if err != nil { - // t.Fatal(err) - // } - - // if st.Size() == 0 { - // t.Fatalf("zero.yml is empty") - // } -} diff --git a/internal/apply/apply.go b/internal/apply/apply.go index e14b6e405..53f9d2832 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -12,6 +12,7 @@ import ( "github.com/commitdev/zero/internal/module" "github.com/commitdev/zero/internal/util" + "github.com/commitdev/zero/internal/config/globalconfig" "github.com/commitdev/zero/internal/config/projectconfig" "github.com/commitdev/zero/pkg/util/exit" "github.com/commitdev/zero/pkg/util/flog" @@ -52,8 +53,11 @@ func applyAll(dir string, projectConfig projectconfig.ZeroProjectConfig, applyEn environmentArg := fmt.Sprintf("ENVIRONMENT=%s", strings.Join(applyEnvironments, ",")) for _, mod := range projectConfig.Modules { - dirArg := fmt.Sprintf("PROJECT_DIR=%s", path.Join(dir, mod.Files.Directory)) - envList := []string{environmentArg, dirArg} + envList := []string{ + environmentArg, + fmt.Sprintf("PROJECT_DIR=%s", path.Join(dir, mod.Files.Directory)), + fmt.Sprintf("REPOSITORY=%s", mod.Files.Repository), + } modulePath := module.GetSourceDir(mod.Files.Source) // Passed in `dir` will only be used to find the project path, not the module path, @@ -62,7 +66,10 @@ func applyAll(dir string, projectConfig projectconfig.ZeroProjectConfig, applyEn modulePath = filepath.Join(dir, modulePath) } + credentials := globalconfig.GetProjectCredentials(projectConfig.Name) + envList = util.AppendProjectEnvToCmdEnv(mod.Parameters, envList) + envList = util.AppendProjectEnvToCmdEnv(credentials.AsEnvVars(), envList) util.ExecuteCommand(exec.Command("make"), modulePath, envList) } } diff --git a/internal/apply/apply_test.go b/internal/apply/apply_test.go index 7f83f9dce..a88daee54 100644 --- a/internal/apply/apply_test.go +++ b/internal/apply/apply_test.go @@ -32,10 +32,10 @@ func TestApply(t *testing.T) { content, err := ioutil.ReadFile(filepath.Join(tmpDir, "project1/project.out")) assert.NoError(t, err) - assert.Equal(t, string(content), "foo: bar\n") + assert.Equal(t, "foo: bar\nrepo: github.com/commitdev/project1\n", string(content)) content, err = ioutil.ReadFile(filepath.Join(tmpDir, "project2/project.out")) assert.NoError(t, err) - assert.Equal(t, string(content), "baz: qux\n") + assert.Equal(t, "baz: qux\n", string(content)) }) } diff --git a/internal/config/globalconfig/global_config.go b/internal/config/globalconfig/global_config.go index 0f1cf91ff..9feb5ddf5 100644 --- a/internal/config/globalconfig/global_config.go +++ b/internal/config/globalconfig/global_config.go @@ -7,6 +7,7 @@ import ( "os" "os/user" "path" + "reflect" "github.com/commitdev/zero/internal/constants" "github.com/commitdev/zero/pkg/util/exit" @@ -25,14 +26,14 @@ type ProjectCredential struct { } type AWSResourceConfig struct { - AccessKeyId string `yaml:"accessKeyId,omitempty"` - SecretAccessKey string `yaml:"secretAccessKey,omitempty"` + AccessKeyID string `yaml:"accessKeyId,omitempty" env:"AWS_ACCESS_KEY_ID"` + SecretAccessKey string `yaml:"secretAccessKey,omitempty" env:"AWS_SECRET_ACCESS_KEY"` } type GithubResourceConfig struct { - AccessToken string `yaml:"accessToken,omitempty"` + AccessToken string `yaml:"accessToken,omitempty" env:"GITHUB_ACCESS_TOKEN"` } type CircleCiResourceConfig struct { - ApiKey string `yaml:"apiKey,omitempty"` + ApiKey string `yaml:"apiKey,omitempty" env:"CIRCLECI_API_KEY"` } func (p ProjectCredentials) Unmarshal(data []byte) error { @@ -50,6 +51,35 @@ func (p ProjectCredentials) Unmarshal(data []byte) error { return nil } +// AsEnvVars marshals ProjectCredential as a map of key/value strings suitable for environment variables +func (p ProjectCredential) AsEnvVars() map[string]string { + t := reflect.ValueOf(p) + + list := make(map[string]string) + list = gatherFieldTags(t, list) + + return list +} + +func gatherFieldTags(t reflect.Value, list map[string]string) map[string]string { + reflectType := t.Type() + + for i := 0; i < t.NumField(); i++ { + fieldValue := t.Field(i) + fieldType := reflectType.Field(i) + + if fieldType.Type.Kind() == reflect.Struct { + list = gatherFieldTags(fieldValue, list) + continue + } + + if env := fieldType.Tag.Get("env"); env != "" { + list[env] = fieldValue.String() + } + } + return list +} + func LoadUserCredentials() ProjectCredentials { data := readOrCreateUserCredentialsFile() diff --git a/internal/config/globalconfig/global_config_test.go b/internal/config/globalconfig/global_config_test.go index 12c47eb4a..9f9278220 100644 --- a/internal/config/globalconfig/global_config_test.go +++ b/internal/config/globalconfig/global_config_test.go @@ -66,7 +66,7 @@ func TestGetUserCredentials(t *testing.T) { project := globalconfig.GetProjectCredentials(projectName) // Reading from fixtures: tests/test_data/configs/credentials.yml - assert.Equal(t, "AKIAABCD", project.AWSResourceConfig.AccessKeyId) + assert.Equal(t, "AKIAABCD", project.AWSResourceConfig.AccessKeyID) assert.Equal(t, "ZXCV", project.AWSResourceConfig.SecretAccessKey) assert.Equal(t, "0987", project.GithubResourceConfig.AccessToken) assert.Equal(t, "SOME_API_KEY", project.CircleCiResourceConfig.ApiKey) @@ -87,17 +87,36 @@ func TestEditUserCredentials(t *testing.T) { t.Run("Should create new project if not exist", func(t *testing.T) { projectName := "test-project3" project := globalconfig.GetProjectCredentials(projectName) - project.AWSResourceConfig.AccessKeyId = "TEST_KEY_ID_1" + project.AWSResourceConfig.AccessKeyID = "TEST_KEY_ID_1" globalconfig.Save(project) - newKeyID := globalconfig.GetProjectCredentials(projectName).AWSResourceConfig.AccessKeyId + newKeyID := globalconfig.GetProjectCredentials(projectName).AWSResourceConfig.AccessKeyID assert.Equal(t, "TEST_KEY_ID_1", newKeyID) }) t.Run("Should edit old project if already exist", func(t *testing.T) { projectName := "my-project" project := globalconfig.GetProjectCredentials(projectName) - project.AWSResourceConfig.AccessKeyId = "EDITED_ACCESS_KEY_ID" + project.AWSResourceConfig.AccessKeyID = "EDITED_ACCESS_KEY_ID" globalconfig.Save(project) - newKeyID := globalconfig.GetProjectCredentials(projectName).AWSResourceConfig.AccessKeyId + newKeyID := globalconfig.GetProjectCredentials(projectName).AWSResourceConfig.AccessKeyID assert.Equal(t, "EDITED_ACCESS_KEY_ID", newKeyID) }) } + +func TestMarshalProjectCredentialAsEnvVars(t *testing.T) { + t.Run("Should be able to marshal a ProjectCredential into env vars", func(t *testing.T) { + pc := globalconfig.ProjectCredential{ + AWSResourceConfig: globalconfig.AWSResourceConfig{ + AccessKeyID: "AKID", + SecretAccessKey: "SAK", + }, + CircleCiResourceConfig: globalconfig.CircleCiResourceConfig{ + ApiKey: "APIKEY", + }, + } + + envVars := pc.AsEnvVars() + assert.Equal(t, "AKID", envVars["AWS_ACCESS_KEY_ID"]) + assert.Equal(t, "SAK", envVars["AWS_SECRET_ACCESS_KEY"]) + assert.Equal(t, "APIKEY", envVars["CIRCLECI_API_KEY"]) + }) +} diff --git a/internal/init/init.go b/internal/init/init.go index 9e72b62b8..67b93e5c8 100644 --- a/internal/init/init.go +++ b/internal/init/init.go @@ -239,7 +239,7 @@ func mapVendorToPrompts(projectCred globalconfig.ProjectCredential, vendor strin moduleconfig.Parameter{ Field: "accessKeyId", Label: "AWS Access Key ID", - Default: projectCred.AWSResourceConfig.AccessKeyId, + Default: projectCred.AWSResourceConfig.AccessKeyID, }, CustomCondition(customAwsMustInputCondition), project.ValidateAKID, diff --git a/tests/test_data/apply/project1/Makefile b/tests/test_data/apply/project1/Makefile index 3df071059..a60a27603 100644 --- a/tests/test_data/apply/project1/Makefile +++ b/tests/test_data/apply/project1/Makefile @@ -1,2 +1,3 @@ current_dir: @echo "foo: ${foo}" > project.out + @echo "repo: ${REPOSITORY}" >> project.out From 0665b3f991bcc449a47296df18c36a1805e96e71 Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Tue, 23 Jun 2020 12:18:59 -0700 Subject: [PATCH 3/8] Fixed caps --- pkg/credentials/credentials.go | 2 +- pkg/credentials/credentials_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/credentials/credentials.go b/pkg/credentials/credentials.go index 9389865f0..0e84de360 100644 --- a/pkg/credentials/credentials.go +++ b/pkg/credentials/credentials.go @@ -55,7 +55,7 @@ func GetAWSProfileCredentials(credsPath string, profileName string, creds global if err != nil { log.Fatal(err) } - creds.AWSResourceConfig.AccessKeyId = awsCreds.AccessKeyID + creds.AWSResourceConfig.AccessKeyID = awsCreds.AccessKeyID creds.AWSResourceConfig.SecretAccessKey = awsCreds.SecretAccessKey return creds } diff --git a/pkg/credentials/credentials_test.go b/pkg/credentials/credentials_test.go index 9386c993a..9c9e3c62c 100644 --- a/pkg/credentials/credentials_test.go +++ b/pkg/credentials/credentials_test.go @@ -13,14 +13,14 @@ func TestFillAWSProfileCredentials(t *testing.T) { t.Run("fills project credentials", func(t *testing.T) { projectCreds := globalconfig.ProjectCredential{} projectCreds = credentials.GetAWSProfileCredentials(mockAwsCredentialFilePath, "default", projectCreds) - assert.Equal(t, "MOCK1_ACCESS_KEY", projectCreds.AWSResourceConfig.AccessKeyId) + assert.Equal(t, "MOCK1_ACCESS_KEY", projectCreds.AWSResourceConfig.AccessKeyID) assert.Equal(t, "MOCK1_SECRET_ACCESS_KEY", projectCreds.AWSResourceConfig.SecretAccessKey) }) t.Run("supports non-default profiles", func(t *testing.T) { projectCreds := globalconfig.ProjectCredential{} projectCreds = credentials.GetAWSProfileCredentials(mockAwsCredentialFilePath, "foobar", projectCreds) - assert.Equal(t, "MOCK2_ACCESS_KEY", projectCreds.AWSResourceConfig.AccessKeyId) + assert.Equal(t, "MOCK2_ACCESS_KEY", projectCreds.AWSResourceConfig.AccessKeyID) assert.Equal(t, "MOCK2_SECRET_ACCESS_KEY", projectCreds.AWSResourceConfig.SecretAccessKey) }) } From 4f379733975aa6113f8e8a2a96af6161c3a895a4 Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Tue, 23 Jun 2020 12:03:23 -0700 Subject: [PATCH 4/8] Some cleanup around prompts / credentials --- internal/init/init.go | 37 +---------- internal/init/prompts.go | 19 ++++++ pkg/credentials/credentials.go | 109 --------------------------------- 3 files changed, 21 insertions(+), 144 deletions(-) diff --git a/internal/init/init.go b/internal/init/init.go index 67b93e5c8..8663d0ab0 100644 --- a/internal/init/init.go +++ b/internal/init/init.go @@ -6,11 +6,6 @@ import ( "path" "sync" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/sts" "github.com/commitdev/zero/internal/config/globalconfig" "github.com/commitdev/zero/internal/config/moduleconfig" "github.com/commitdev/zero/internal/config/projectconfig" @@ -242,7 +237,7 @@ func mapVendorToPrompts(projectCred globalconfig.ProjectCredential, vendor strin Default: projectCred.AWSResourceConfig.AccessKeyID, }, CustomCondition(customAwsMustInputCondition), - project.ValidateAKID, + ValidateAKID, }, { moduleconfig.Parameter{ @@ -251,7 +246,7 @@ func mapVendorToPrompts(projectCred globalconfig.ProjectCredential, vendor strin Default: projectCred.AWSResourceConfig.SecretAccessKey, }, CustomCondition(customAwsMustInputCondition), - project.ValidateSAK, + ValidateSAK, }, } prompts = append(prompts, awsPrompts...) @@ -311,34 +306,6 @@ func chooseStack(reg registry.Registry) []string { return registry.GetModulesByName(reg, providerResult) } -func fillProviderDetails(projectConfig *projectconfig.ZeroProjectConfig, s project.Secrets) { - if projectConfig.Infrastructure.AWS != nil { - sess, err := session.NewSession(&aws.Config{ - Region: aws.String(projectConfig.Infrastructure.AWS.Region), - Credentials: credentials.NewStaticCredentials(s.AWS.AccessKeyID, s.AWS.SecretAccessKey, ""), - }) - - svc := sts.New(sess) - input := &sts.GetCallerIdentityInput{} - - awsCaller, err := svc.GetCallerIdentity(input) - if err != nil { - if aerr, ok := err.(awserr.Error); ok { - switch aerr.Code() { - default: - exit.Error(aerr.Error()) - } - } else { - exit.Error(err.Error()) - } - } - - if awsCaller != nil && awsCaller.Account != nil { - projectConfig.Infrastructure.AWS.AccountID = *awsCaller.Account - } - } -} - func defaultProjConfig() projectconfig.ZeroProjectConfig { return projectconfig.ZeroProjectConfig{ Name: "", diff --git a/internal/init/prompts.go b/internal/init/prompts.go index d31ab9648..d976a4c4c 100644 --- a/internal/init/prompts.go +++ b/internal/init/prompts.go @@ -1,6 +1,7 @@ package init import ( + "errors" "fmt" "log" "os" @@ -68,6 +69,24 @@ func SpecificValueValidation(values ...string) func(string) error { } } +func ValidateAKID(input string) error { + // 20 uppercase alphanumeric characters + var awsAccessKeyIDPat = regexp.MustCompile(`^[A-Z0-9]{20}$`) + if !awsAccessKeyIDPat.MatchString(input) { + return errors.New("Invalid aws_access_key_id") + } + return nil +} + +func ValidateSAK(input string) error { + // 40 base64 characters + var awsSecretAccessKeyPat = regexp.MustCompile(`^[A-Za-z0-9/+=]{40}$`) + if !awsSecretAccessKeyPat.MatchString(input) { + return errors.New("Invalid aws_secret_access_key") + } + return nil +} + // TODO: validation / allow prompt retry ...etc func (p PromptHandler) GetParam(projectParams map[string]string) string { var err error diff --git a/pkg/credentials/credentials.go b/pkg/credentials/credentials.go index 0e84de360..2abe8b751 100644 --- a/pkg/credentials/credentials.go +++ b/pkg/credentials/credentials.go @@ -1,42 +1,16 @@ package credentials import ( - "errors" - "fmt" "io/ioutil" "log" - "os" "os/user" "path/filepath" "regexp" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/commitdev/zero/internal/config/globalconfig" - "github.com/commitdev/zero/internal/config/projectconfig" - "github.com/manifoldco/promptui" ) -// Secrets - AWS prompted credentials -type Secrets struct { - AWS AWS - CircleCIKey string - GithubToken string -} - -type AWS struct { - AccessKeyID string - SecretAccessKey string -} - -func MakeAwsEnvars(cfg *projectconfig.ZeroProjectConfig, awsSecrets Secrets) []string { - env := os.Environ() - env = append(env, fmt.Sprintf("AWS_ACCESS_KEY_ID=%s", awsSecrets.AWS.AccessKeyID)) - env = append(env, fmt.Sprintf("AWS_SECRET_ACCESS_KEY=%s", awsSecrets.AWS.SecretAccessKey)) - env = append(env, fmt.Sprintf("AWS_DEFAULT_REGION=%s", cfg.Infrastructure.AWS.Region)) - - return env -} - func AwsCredsPath() string { usr, err := user.Current() if err != nil { @@ -82,86 +56,3 @@ func GetAWSProfiles() ([]string, error) { } return profiles, nil } - -func ValidateAKID(input string) error { - // 20 uppercase alphanumeric characters - var awsAccessKeyIDPat = regexp.MustCompile(`^[A-Z0-9]{20}$`) - if !awsAccessKeyIDPat.MatchString(input) { - return errors.New("Invalid aws_access_key_id") - } - return nil -} - -func ValidateSAK(input string) error { - // 40 base64 characters - var awsSecretAccessKeyPat = regexp.MustCompile(`^[A-Za-z0-9/+=]{40}$`) - if !awsSecretAccessKeyPat.MatchString(input) { - return errors.New("Invalid aws_secret_access_key") - } - return nil -} - -func promptAWSCredentials(secrets *Secrets) { - accessKeyIDPrompt := promptui.Prompt{ - Label: "Aws Access Key ID ", - Validate: ValidateAKID, - } - - accessKeyIDResult, err := accessKeyIDPrompt.Run() - - if err != nil { - log.Fatalf("Prompt failed %v\n", err) - panic(err) - } - - secretAccessKeyPrompt := promptui.Prompt{ - Label: "Aws Secret Access Key ", - Validate: ValidateSAK, - Mask: '*', - } - - secretAccessKeyResult, err := secretAccessKeyPrompt.Run() - - if err != nil { - log.Fatalf("Prompt failed %v\n", err) - panic(err) - } - - secrets.AWS.AccessKeyID = accessKeyIDResult - secrets.AWS.SecretAccessKey = secretAccessKeyResult -} - -func promptGitHubCredentials(secrets *Secrets) { -} - -func promptCircleCICredentials(secrets *Secrets) { - validateKey := func(input string) error { - // 40 base64 characters - var awsSecretAccessKeyPat = regexp.MustCompile(`^[A-Za-z0-9]{40}$`) - if !awsSecretAccessKeyPat.MatchString(input) { - return errors.New("Invalid CircleCI API Key") - } - return nil - } - - prompt := promptui.Prompt{ - Label: "Please enter your CircleCI API key (you can create one at https://circleci.com/account/api) ", - Validate: validateKey, - } - - key, err := prompt.Run() - - if err != nil { - log.Fatalf("Prompt failed %v\n", err) - panic(err) - } - secrets.CircleCIKey = key -} - -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if os.IsNotExist(err) { - return false - } - return !info.IsDir() -} From 677667d10d135ce41ea3139cdc893ba258fbbd4b Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Tue, 23 Jun 2020 12:20:36 -0700 Subject: [PATCH 5/8] Mod tidy --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 6106a2703..12988a9dc 100644 --- a/go.sum +++ b/go.sum @@ -42,7 +42,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -143,7 +142,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/moby/moby v1.13.1 h1:mC5WwQwCXt/dYxZ1cIrRsnJAWw7VdtcTZUIGr4tXzOM= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= From 46cb194e81c9d571e42733b315478a833d9efa5b Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Tue, 23 Jun 2020 12:25:08 -0700 Subject: [PATCH 6/8] Use only parent env vars when executing if no others provided --- go.sum | 2 ++ internal/apply/apply.go | 3 +++ internal/util/util.go | 2 ++ 3 files changed, 7 insertions(+) diff --git a/go.sum b/go.sum index 12988a9dc..6106a2703 100644 --- a/go.sum +++ b/go.sum @@ -42,6 +42,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -142,6 +143,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/moby v1.13.1 h1:mC5WwQwCXt/dYxZ1cIrRsnJAWw7VdtcTZUIGr4tXzOM= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= diff --git a/internal/apply/apply.go b/internal/apply/apply.go index 53f9d2832..af14fe64e 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -52,7 +52,9 @@ Only a single environment may be suitable for an initial test, but for a real sy func applyAll(dir string, projectConfig projectconfig.ZeroProjectConfig, applyEnvironments []string) { environmentArg := fmt.Sprintf("ENVIRONMENT=%s", strings.Join(applyEnvironments, ",")) + // Go through each of the modules and run `make` for _, mod := range projectConfig.Modules { + // Add env vars for the makefile envList := []string{ environmentArg, fmt.Sprintf("PROJECT_DIR=%s", path.Join(dir, mod.Files.Directory)), @@ -66,6 +68,7 @@ func applyAll(dir string, projectConfig projectconfig.ZeroProjectConfig, applyEn modulePath = filepath.Join(dir, modulePath) } + // Get project credentials for the makefile credentials := globalconfig.GetProjectCredentials(projectConfig.Name) envList = util.AppendProjectEnvToCmdEnv(mod.Parameters, envList) diff --git a/internal/util/util.go b/internal/util/util.go index b427c1858..f9c09c43f 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -59,6 +59,7 @@ func ExecuteCommand(cmd *exec.Cmd, pathPrefix string, envars []string) { var errStdout, errStderr error + cmd.Env = os.Environ() if envars != nil { cmd.Env = append(os.Environ(), envars...) } @@ -99,6 +100,7 @@ func ExecuteCommandOutput(cmd *exec.Cmd, pathPrefix string, envars []string) str cmd.Dir = path.Join(dir, pathPrefix) } + cmd.Env = os.Environ() if envars != nil { cmd.Env = append(os.Environ(), envars...) } From 23a4af5934af20b31fff2a751fc5fbbd246ff809 Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Tue, 23 Jun 2020 13:32:59 -0700 Subject: [PATCH 7/8] Fixed file name --- internal/apply/apply.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/apply/apply.go b/internal/apply/apply.go index af14fe64e..3313d3854 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -33,9 +33,7 @@ Only a single environment may be suitable for an initial test, but for a real sy environments = promptEnvironments() } - validateEnvironments(environments) - - flog.Infof(":tada: Bootstrapping project %s. Please use the zero.yml file to modify the project as needed.", projectConfig.Name) + flog.Infof(":tada: Bootstrapping project %s. Please use the zero-project.yml file to modify the project as needed.", projectConfig.Name) flog.Infof("Cloud provider: %s", "AWS") // will this come from the config? From 682d8d04784582b623a15482eac94753112a2aa7 Mon Sep 17 00:00:00 2001 From: Bill Monkman Date: Wed, 24 Jun 2020 10:01:20 -0700 Subject: [PATCH 8/8] Removed stray context from test data --- tests/test_data/apply/zero-project.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_data/apply/zero-project.yml b/tests/test_data/apply/zero-project.yml index 114ca1c99..09c239cfc 100644 --- a/tests/test_data/apply/zero-project.yml +++ b/tests/test_data/apply/zero-project.yml @@ -1,7 +1,5 @@ name: sample_project -context: - modules: project1: parameters: