From 107f0e8cd74865319324278d292730090068513c Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:09:21 -0700 Subject: [PATCH 01/44] adding logic for generating default app name --- pkg/prompts/prompts.go | 71 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 9dbac56e..61ebe470 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -4,6 +4,9 @@ import ( "errors" "fmt" "io" + "os" + "path/filepath" + "regexp" "strings" "github.com/manifoldco/promptui" @@ -79,6 +82,21 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal VariableDefault.Value in that order. func GetVariableDefaultValue(variableName string, variableDefaults []config.BuilderVarDefault, inputs map[string]string) string { defaultValue := "" + + if variableName == "APPNAME" { + dirName, err := getCurrentDirName() //draft + if err != nil { + log.Errorf("Error retrieving current directory name: %v", err) + return "my-app" // Default to "my-app" if there's an error + } + defaultValue = sanitizeAppName(dirName) + // If the sanitized directory name is invalid, default to "my-app" + if defaultValue == "" { + defaultValue = "my-app" + } + return defaultValue + } + for _, variableDefault := range variableDefaults { if variableDefault.Name == variableName { defaultValue = variableDefault.Value @@ -153,9 +171,19 @@ func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue str if err != nil { return "", err } - // Variable-level substitution, we need to get defaults so later references can be resolved in this loop - if input == "" && defaultString != "" { - input = defaultValue + if customPrompt.Name == "APPNAME" { + // Sanitize the user input + sanitizedInput := sanitizeAppName(input) + if sanitizedInput == "" { + // If sanitized input is empty, use the sanitized directory-based name + sanitizedInput = defaultValue + } + input = sanitizedInput + } else { + // Variable-level substitution, we need to get defaults so later references can be resolved in this loop + if input == "" && defaultString != "" { + input = defaultValue + } } return input, nil } @@ -244,3 +272,40 @@ func Select[T any](label string, items []T, opt *SelectOpt[T]) (T, error) { return items[i], nil } + +func getCurrentDirName() (string, error) { + dir, err := os.Getwd() + if err != nil { + log.Fatalf("getting current directory: %v", err) + } + return filepath.Base(dir), nil +} + +// Sanitize the directory name to comply with k8s label rules +func sanitizeAppName(name string) string { + // Remove all characters except alphanumeric, '-', '_', '.' + reg := regexp.MustCompile(`[^a-zA-Z0-9-_.]+`) + sanitized := reg.ReplaceAllString(name, "") + + // Trim leading and trailing '-', '_', '.' + sanitized = strings.Trim(sanitized, "-._") + + // If name is empty, return empty string + if sanitized == "" { + return "" + } + + // Ensure appname starts with alphanumeric characters + regStart := regexp.MustCompile(`^[^a-zA-Z0-9]+`) + sanitized = regStart.ReplaceAllString(sanitized, "") + + // Ensure appname ends with alphanumeric characters + regEnd := regexp.MustCompile(`[^a-zA-Z0-9]+$`) + sanitized = regEnd.ReplaceAllString(sanitized, "") + + if len(sanitized) > 63 { + sanitized = sanitized[:63] + } + + return sanitized +} From b043d0661bd44d7947f86c68bfc24a79b0add884 Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:21:58 -0700 Subject: [PATCH 02/44] updated the sanitize function and added validator for appApp --- pkg/prompts/prompts.go | 127 ++++++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 51 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 61ebe470..1c37e042 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -6,8 +6,8 @@ import ( "io" "os" "path/filepath" - "regexp" "strings" + "unicode" "github.com/manifoldco/promptui" log "github.com/sirupsen/logrus" @@ -15,6 +15,8 @@ import ( "github.com/Azure/draft/pkg/config" ) +const defaultAppName = "my-app" + func RunPromptsFromConfig(config *config.DraftConfig) (map[string]string, error) { return RunPromptsFromConfigWithSkips(config, []string{}) } @@ -84,16 +86,13 @@ func GetVariableDefaultValue(variableName string, variableDefaults []config.Buil defaultValue := "" if variableName == "APPNAME" { - dirName, err := getCurrentDirName() //draft + dirName, err := getCurrentDirName() if err != nil { - log.Errorf("Error retrieving current directory name: %v", err) - return "my-app" // Default to "my-app" if there's an error + log.Errorf("Error retrieving current directory name: %s", err) + return defaultAppName } defaultValue = sanitizeAppName(dirName) - // If the sanitized directory name is invalid, default to "my-app" - if defaultValue == "" { - defaultValue = "my-app" - } + return defaultValue } @@ -147,11 +146,40 @@ func NoBlankStringValidator(s string) error { return nil } +// Validator for App name +func appNameValidator(name string) error { + if name == "" { + return fmt.Errorf("application name cannot be empty") + } + + if !unicode.IsLetter(rune(name[0])) && !unicode.IsDigit(rune(name[0])) { + return fmt.Errorf("application name must start with a letter or digit") + } + + if name[len(name)-1] == '-' || name[len(name)-1] == '_' || name[len(name)-1] == '.' { + return fmt.Errorf("application name cannot end with '-', '_', or '.'") + } + + for _, r := range name { + if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '-' && r != '_' && r != '.' { + return fmt.Errorf("application name can only contain letters, digits, '-', '_', and '.'") + } + } + + if len(name) > 63 { + return fmt.Errorf("application name cannot be longer than 63 characters") + } + + return nil +} + // RunDefaultableStringPrompt runs a prompt for a string variable, returning the user string input for the prompt func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue string, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) { var validatorFunc func(string) error if validate == nil { validatorFunc = NoBlankStringValidator + } else { + validatorFunc = validate } defaultString := "" @@ -160,32 +188,33 @@ func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue str defaultString = " (default: " + defaultValue + ")" } - prompt := &promptui.Prompt{ - Label: "Please enter " + customPrompt.Description + defaultString, - Validate: validatorFunc, - Stdin: Stdin, - Stdout: Stdout, - } + for { + prompt := &promptui.Prompt{ + Label: "Please enter " + customPrompt.Description + defaultString, + Validate: validatorFunc, + Stdin: Stdin, + Stdout: Stdout, + } - input, err := prompt.Run() - if err != nil { - return "", err - } - if customPrompt.Name == "APPNAME" { - // Sanitize the user input - sanitizedInput := sanitizeAppName(input) - if sanitizedInput == "" { - // If sanitized input is empty, use the sanitized directory-based name - sanitizedInput = defaultValue + input, err := prompt.Run() + if err != nil { + return "", err } - input = sanitizedInput - } else { - // Variable-level substitution, we need to get defaults so later references can be resolved in this loop - if input == "" && defaultString != "" { - input = defaultValue + if customPrompt.Name == "APPNAME" { + err := appNameValidator(input) + if err != nil { + fmt.Println(err.Error()) + continue + } + input = sanitizeAppName(input) + } else { + // Variable-level substitution, we need to get defaults so later references can be resolved in this loop + if input == "" && defaultString != "" { + input = defaultValue + } } + return input, nil } - return input, nil } func GetInputFromPrompt(desiredInput string) string { @@ -276,36 +305,32 @@ func Select[T any](label string, items []T, opt *SelectOpt[T]) (T, error) { func getCurrentDirName() (string, error) { dir, err := os.Getwd() if err != nil { - log.Fatalf("getting current directory: %v", err) + fmt.Errorf("getting current directory: %v", err) } return filepath.Base(dir), nil } // Sanitize the directory name to comply with k8s label rules func sanitizeAppName(name string) string { - // Remove all characters except alphanumeric, '-', '_', '.' - reg := regexp.MustCompile(`[^a-zA-Z0-9-_.]+`) - sanitized := reg.ReplaceAllString(name, "") + var builder strings.Builder - // Trim leading and trailing '-', '_', '.' - sanitized = strings.Trim(sanitized, "-._") - - // If name is empty, return empty string - if sanitized == "" { - return "" + // Remove all characters except alphanumeric, '-', '_', '.' + for _, r := range name { + if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '-' || r == '_' || r == '.' { + builder.WriteRune(r) + } } - // Ensure appname starts with alphanumeric characters - regStart := regexp.MustCompile(`^[^a-zA-Z0-9]+`) - sanitized = regStart.ReplaceAllString(sanitized, "") - - // Ensure appname ends with alphanumeric characters - regEnd := regexp.MustCompile(`[^a-zA-Z0-9]+$`) - sanitized = regEnd.ReplaceAllString(sanitized, "") - - if len(sanitized) > 63 { - sanitized = sanitized[:63] + sanitized := builder.String() + if sanitized == "" { + sanitized = defaultAppName + } else { + // Trim leading and trailing '-', '_', '.' + sanitized = strings.Trim(sanitized, "-._") + // Ensure the length does not exceed 63 characters + if len(sanitized) > 63 { + sanitized = sanitized[:63] + } } - return sanitized } From b9d68b925e3b3e35765d347fbd49ac85d41f9304 Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:24:03 -0700 Subject: [PATCH 03/44] addressing comments --- pkg/prompts/prompts.go | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 1c37e042..7f6e5764 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -82,6 +82,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st } // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal VariableDefault.Value in that order. + func GetVariableDefaultValue(variableName string, variableDefaults []config.BuilderVarDefault, inputs map[string]string) string { defaultValue := "" @@ -92,7 +93,6 @@ func GetVariableDefaultValue(variableName string, variableDefaults []config.Buil return defaultAppName } defaultValue = sanitizeAppName(dirName) - return defaultValue } @@ -157,7 +157,7 @@ func appNameValidator(name string) error { } if name[len(name)-1] == '-' || name[len(name)-1] == '_' || name[len(name)-1] == '.' { - return fmt.Errorf("application name cannot end with '-', '_', or '.'") + return fmt.Errorf("application name must end with a letter or digit") } for _, r := range name { @@ -175,34 +175,30 @@ func appNameValidator(name string) error { // RunDefaultableStringPrompt runs a prompt for a string variable, returning the user string input for the prompt func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue string, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) { - var validatorFunc func(string) error if validate == nil { - validatorFunc = NoBlankStringValidator - } else { - validatorFunc = validate + validate = NoBlankStringValidator } defaultString := "" if defaultValue != "" { - validatorFunc = AllowAllStringValidator + validate = AllowAllStringValidator defaultString = " (default: " + defaultValue + ")" } + prompt := &promptui.Prompt{ + Label: "Please enter " + customPrompt.Description + defaultString, + Validate: validate, + Default: defaultValue, + Stdin: Stdin, + Stdout: Stdout, + } for { - prompt := &promptui.Prompt{ - Label: "Please enter " + customPrompt.Description + defaultString, - Validate: validatorFunc, - Stdin: Stdin, - Stdout: Stdout, - } - input, err := prompt.Run() if err != nil { return "", err } if customPrompt.Name == "APPNAME" { - err := appNameValidator(input) - if err != nil { + if err := appNameValidator(input); err != nil { fmt.Println(err.Error()) continue } From 66521b0b405226440b9b9897c498efaa4f83fbb4 Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Tue, 11 Jun 2024 22:54:09 -0700 Subject: [PATCH 04/44] added the validator for app name and unit tests --- pkg/prompts/prompts.go | 59 ++++++++++++++----------- pkg/prompts/prompts_test.go | 88 ++++++++++++++++++++++++++----------- 2 files changed, 96 insertions(+), 51 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 7f6e5764..a97928d0 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -17,6 +17,9 @@ import ( const defaultAppName = "my-app" +// Function to get current directory name +var getCurrentDirNameFunc = getCurrentDirName + func RunPromptsFromConfig(config *config.DraftConfig) (map[string]string, error) { return RunPromptsFromConfigWithSkips(config, []string{}) } @@ -82,12 +85,11 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st } // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal VariableDefault.Value in that order. - func GetVariableDefaultValue(variableName string, variableDefaults []config.BuilderVarDefault, inputs map[string]string) string { defaultValue := "" if variableName == "APPNAME" { - dirName, err := getCurrentDirName() + dirName, err := getCurrentDirNameFunc() if err != nil { log.Errorf("Error retrieving current directory name: %s", err) return defaultAppName @@ -179,38 +181,44 @@ func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue str validate = NoBlankStringValidator } + validatorFunc := func(input string) error { + // Allow blank inputs because defaults are set later + if input == "" { + return nil + } + if customPrompt.Name == "APPNAME" { + if err := appNameValidator(input); err != nil { + return err + } + } else { + if err := validate(input); err != nil { + return err + } + } + return nil + } + defaultString := "" if defaultValue != "" { - validate = AllowAllStringValidator defaultString = " (default: " + defaultValue + ")" } prompt := &promptui.Prompt{ Label: "Please enter " + customPrompt.Description + defaultString, - Validate: validate, - Default: defaultValue, + Validate: validatorFunc, Stdin: Stdin, Stdout: Stdout, } - for { - input, err := prompt.Run() - if err != nil { - return "", err - } - if customPrompt.Name == "APPNAME" { - if err := appNameValidator(input); err != nil { - fmt.Println(err.Error()) - continue - } - input = sanitizeAppName(input) - } else { - // Variable-level substitution, we need to get defaults so later references can be resolved in this loop - if input == "" && defaultString != "" { - input = defaultValue - } - } - return input, nil + + input, err := prompt.Run() + if err != nil { + return "", err } + + if input == "" && defaultValue != "" { + input = defaultValue + } + return input, nil } func GetInputFromPrompt(desiredInput string) string { @@ -301,9 +309,10 @@ func Select[T any](label string, items []T, opt *SelectOpt[T]) (T, error) { func getCurrentDirName() (string, error) { dir, err := os.Getwd() if err != nil { - fmt.Errorf("getting current directory: %v", err) + return "", fmt.Errorf("getting current directory: %v", err) } - return filepath.Base(dir), nil + dirName := filepath.Base(dir) + return sanitizeAppName(dirName), nil } // Sanitize the directory name to comply with k8s label rules diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index 689ead70..fb89b294 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -80,12 +80,13 @@ func TestGetVariableDefaultValue(t *testing.T) { func TestRunStringPrompt(t *testing.T) { tests := []struct { - testName string - prompt config.BuilderVar - userInputs []string - defaultValue string - want string - wantErr bool + testName string + prompt config.BuilderVar + userInputs []string + defaultValue string + want string + wantErr bool + mockDirNameValue string }{ { testName: "basicPrompt", @@ -93,10 +94,11 @@ func TestRunStringPrompt(t *testing.T) { Name: "var1", Description: "var1 description", }, - userInputs: []string{"value-1\n"}, - defaultValue: "input", - want: "value-1", - wantErr: false, + userInputs: []string{"value-1\n"}, + defaultValue: "input", + want: "value-1", + wantErr: false, + mockDirNameValue: "", }, { testName: "promptWithDefault", @@ -104,14 +106,47 @@ func TestRunStringPrompt(t *testing.T) { Name: "var1", Description: "var1 description", }, - userInputs: []string{"\n"}, - defaultValue: "defaultValue", - want: "defaultValue", - wantErr: false, + userInputs: []string{"\n"}, + defaultValue: "defaultValue", + want: "defaultValue", + wantErr: false, + mockDirNameValue: "", + }, + { + testName: "appNameUsesDirName", + prompt: config.BuilderVar{ + Name: "APPNAME", + Description: "app name", + }, + userInputs: []string{"\n"}, + defaultValue: "currentdir", + want: "currentdir", + wantErr: false, + mockDirNameValue: "currentdir", + }, + { + testName: "invalidAppName", + prompt: config.BuilderVar{ + Name: "APPNAME", + Description: "app name", + }, + userInputs: []string{"--invalid-app-name\n"}, + defaultValue: "defaultApp", + want: "", + wantErr: true, + mockDirNameValue: "currentdir", }, } + for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { + // Mock the getCurrentDirNameFunc for testing + originalGetCurrentDirNameFunc := getCurrentDirNameFunc + defer func() { getCurrentDirNameFunc = originalGetCurrentDirNameFunc }() + getCurrentDirNameFunc = func() (string, error) { + return tt.mockDirNameValue, nil + } + inReader, inWriter := io.Pipe() go func() { @@ -138,6 +173,7 @@ func TestRunStringPrompt(t *testing.T) { }) } } + func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { tests := []struct { testName string @@ -152,14 +188,14 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { config: config.DraftConfig{ Variables: []config.BuilderVar{ { - Name: "var1", - Description: "var1 description", + Name: "var1", + Description: "var1 description", }, }, VariableDefaults: []config.BuilderVarDefault{ { - Name: "var1", - Value: "defaultValue", + Name: "var1", + Value: "defaultValue", IsPromptDisabled: true, }, }, @@ -174,14 +210,14 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { config: config.DraftConfig{ Variables: []config.BuilderVar{ { - Name: "var1-no-prompt", - Description: "var1 has IsPromptDisabled and should skip prompt and use default value", + Name: "var1-no-prompt", + Description: "var1 has IsPromptDisabled and should skip prompt and use default value", }, { Name: "var2-default", Description: "var2 has a default value and will receive an empty value, so it should use the default value", }, { - Name: "var3-no-prompt", - Description: "var3 has IsPromptDisabled and should skip prompt and use default value", + Name: "var3-no-prompt", + Description: "var3 has IsPromptDisabled and should skip prompt and use default value", }, { Name: "var4", Description: "var4 has a default value, but has a value entered, so it should use the entered value", @@ -189,15 +225,15 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { }, VariableDefaults: []config.BuilderVarDefault{ { - Name: "var1-no-prompt", - Value: "defaultValueNoPrompt1", + Name: "var1-no-prompt", + Value: "defaultValueNoPrompt1", IsPromptDisabled: true, }, { Name: "var2-default", Value: "defaultValue2", }, { - Name: "var3-no-prompt", - Value: "defaultValueNoPrompt3", + Name: "var3-no-prompt", + Value: "defaultValueNoPrompt3", IsPromptDisabled: true, }, { Name: "var4", From 94a19136ebdb9d2f7a6b46035a8491f1c3386e62 Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Wed, 12 Jun 2024 11:17:52 -0700 Subject: [PATCH 05/44] address comments --- pkg/prompts/prompts.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index a97928d0..e4514166 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -198,13 +198,8 @@ func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue str return nil } - defaultString := "" - if defaultValue != "" { - defaultString = " (default: " + defaultValue + ")" - } - prompt := &promptui.Prompt{ - Label: "Please enter " + customPrompt.Description + defaultString, + Label: "Please enter " + customPrompt.Description + " (default: " + defaultValue + ")", Validate: validatorFunc, Stdin: Stdin, Stdout: Stdout, From cad4954a3d46315e407e0e68e2c94698f6d6b7f9 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 18 Jun 2024 16:44:20 -0400 Subject: [PATCH 06/44] kitchen sink --- cmd/create.go | 51 +++++++------- pkg/config/draftconfig.go | 56 +++++++++------ pkg/osutil/osutil.go | 8 +-- pkg/prompts/prompts.go | 68 +++++++------------ pkg/workflows/workflows.go | 29 ++++++++ .../addons/azure/webapp_routing/draft.yaml | 12 ++-- template/deployments/helm/draft.yaml | 37 ++++------ template/deployments/kustomize/draft.yaml | 35 ++++------ template/deployments/manifests/draft.yaml | 35 ++++------ template/dockerfiles/clojure/draft.yaml | 13 ++-- template/dockerfiles/csharp/draft.yaml | 13 ++-- template/dockerfiles/erlang/draft.yaml | 17 ++--- template/dockerfiles/go/draft.yaml | 13 ++-- template/dockerfiles/gomodule/draft.yaml | 15 ++-- template/dockerfiles/gradle/draft.yaml | 22 +++--- template/dockerfiles/gradlew/draft.yaml | 18 ++--- template/dockerfiles/java/draft.yaml | 18 ++--- template/dockerfiles/javascript/draft.yaml | 13 ++-- template/dockerfiles/php/draft.yaml | 18 ++--- template/dockerfiles/python/draft.yaml | 18 ++--- template/dockerfiles/ruby/draft.yaml | 13 ++-- template/dockerfiles/rust/draft.yaml | 13 ++-- template/dockerfiles/swift/draft.yaml | 13 ++-- .../azure-kubernetes-service-helm.yml | 22 +++--- template/workflows/helm/draft.yaml | 59 ++++++++++++---- .../azure-kubernetes-service-kustomize.yml | 14 ++-- template/workflows/kustomize/draft.yaml | 49 +++++++++---- .../workflows/azure-kubernetes-service.yml | 15 ++-- template/workflows/manifests/draft.yaml | 49 +++++++++---- 29 files changed, 400 insertions(+), 356 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index 5fa7545b..b1812c27 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -265,21 +265,14 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan return err } - // Check for existing duplicate defualts + // Check for existing duplicate defaults for k, v := range extractedValues { - variableExists := false - for i, varD := range langConfig.VariableDefaults { - if k == varD.Name { - variableExists = true - langConfig.VariableDefaults[i].Value = v - break - } - } - if !variableExists { - langConfig.VariableDefaults = append(langConfig.VariableDefaults, config.BuilderVarDefault{ - Name: k, + if builderVar, ok := langConfig.Variables[k]; ok { + builderVar.Value = v + } else { + langConfig.Variables[k] = config.BuilderVar{ Value: v, - }) + } } } @@ -290,7 +283,7 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan return err } } else { - inputs, err = validateConfigInputsToPrompts(langConfig.Variables, cc.createConfig.LanguageVariables, langConfig.VariableDefaults) + inputs, err = validateConfigInputsToPrompts(langConfig.Variables, cc.createConfig.LanguageVariables) if err != nil { return err } @@ -328,7 +321,7 @@ func (cc *createCmd) createDeployment() error { if deployConfig == nil { return errors.New("invalid deployment type") } - customInputs, err = validateConfigInputsToPrompts(deployConfig.Variables, cc.createConfig.DeployVariables, deployConfig.VariableDefaults) + customInputs, err = validateConfigInputsToPrompts(deployConfig.Variables, cc.createConfig.DeployVariables) if err != nil { return err } @@ -462,7 +455,7 @@ func init() { rootCmd.AddCommand(newCreateCmd()) } -func validateConfigInputsToPrompts(required []config.BuilderVar, provided []UserInputs, defaults []config.BuilderVarDefault) (map[string]string, error) { +func validateConfigInputsToPrompts(required map[string]config.BuilderVar, provided []UserInputs) (map[string]string, error) { customInputs := make(map[string]string) // set inputs to provided values @@ -471,24 +464,28 @@ func validateConfigInputsToPrompts(required []config.BuilderVar, provided []User } // fill in missing vars using variable default references - for _, variableDefault := range defaults { - if customInputs[variableDefault.Name] == "" && variableDefault.ReferenceVar != "" { - log.Debugf("variable %s is empty, using default referenceVar value from %s", variableDefault.Name, variableDefault.ReferenceVar) - customInputs[variableDefault.Name] = customInputs[variableDefault.ReferenceVar] + for name, variable := range required { + if customInputs[name] == "" && variable.ReferenceVar != "" { + if _, ok := customInputs[variable.ReferenceVar]; !ok { + log.Debugf("reference variable %s is empty, adding it in", variable.ReferenceVar) + customInputs[variable.ReferenceVar] = required[variable.ReferenceVar].DefaultValue + } + log.Debugf("variable %s is empty, using default referenceVar value from %s", name, variable.ReferenceVar) + customInputs[name] = customInputs[variable.ReferenceVar] } } // fill in missing vars using variable default values - for _, variableDefault := range defaults { - if customInputs[variableDefault.Name] == "" && variableDefault.Value != "" { - log.Debugf("setting default value for %s to %s", variableDefault.Name, variableDefault.Value) - customInputs[variableDefault.Name] = variableDefault.Value + for name, variable := range required { + if customInputs[name] == "" && variable.DefaultValue != "" { + log.Debugf("variable %s is empty, using default value %s", name, variable.DefaultValue) + customInputs[name] = variable.DefaultValue } } - for _, variable := range required { - if _, ok := customInputs[variable.Name]; !ok { - return nil, fmt.Errorf("config missing required variable: %s with description: %s", variable.Name, variable.Description) + for name, variable := range required { + if _, ok := customInputs[name]; !ok { + return nil, fmt.Errorf("config missing required variable: %s with description: %s", name, variable.Description) } } diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 05b53864..8f087855 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -1,15 +1,16 @@ package config import ( + "errors" + log "github.com/sirupsen/logrus" ) // TODO: remove Name Overrides since we don't need them anymore type DraftConfig struct { - DisplayName string `yaml:"displayName"` - NameOverrides []FileNameOverride `yaml:"nameOverrides"` - Variables []BuilderVar `yaml:"variables"` - VariableDefaults []BuilderVarDefault `yaml:"variableDefaults"` + DisplayName string `yaml:"displayName"` + NameOverrides []FileNameOverride `yaml:"nameOverrides"` + Variables map[string]BuilderVar `yaml:"variables"` nameOverrideMap map[string]string } @@ -20,26 +21,24 @@ type FileNameOverride struct { } type BuilderVar struct { - Name string `yaml:"name"` + DefaultValue string `yaml:"default"` Description string `yaml:"description"` - VarType string `yaml:"type"` ExampleValues []string `yaml:"exampleValues"` -} - -type BuilderVarDefault struct { - Name string `yaml:"name"` - Value string `yaml:"value"` - ReferenceVar string `yaml:"referenceVar"` - IsPromptDisabled bool `yaml:"disablePrompt"` + IsPromptDisabled bool `yaml:"disablePrompt"` + ReferenceVar string `yaml:"referenceVar"` + ResourceType string `yaml:"resource"` + Type string `yaml:"type"` + Value string `yaml:"value"` } func (d *DraftConfig) GetVariableExampleValues() map[string][]string { variableExampleValues := make(map[string][]string) - for _, variable := range d.Variables { + for name, variable := range d.Variables { if len(variable.ExampleValues) > 0 { - variableExampleValues[variable.Name] = variable.ExampleValues + variableExampleValues[name] = variable.ExampleValues } } + return variableExampleValues } @@ -65,17 +64,34 @@ func (d *DraftConfig) GetNameOverride(path string) string { } // ApplyDefaultVariables will apply the defaults to variables that are not already set -func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) { - for _, variable := range d.VariableDefaults { +func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) error { + for name, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling - if defaultVal, ok := customConfig[variable.Name]; !ok || defaultVal == "" { - log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Value) - customConfig[variable.Name] = variable.Value + if defaultVal, ok := customConfig[name]; !ok || defaultVal == "" { + if variable.Value == "" { + return errors.New("variable " + name + " has no default value") + } + log.Infof("Variable %s defaulting to value %s", name, variable.Value) + customConfig[name] = variable.Value } } + + return nil } // TemplateVariableRecorder is an interface for recording variables that are used read using draft configs type TemplateVariableRecorder interface { Record(key, value string) } + +func (d *DraftConfig) VariableMap() (map[string]string, error) { + varMap := make(map[string]string) + for name, variable := range d.Variables { + if variable.Value == "" { + return nil, errors.New("variable " + name + " has no default value") + } + varMap[name] = variable.Value + } + + return varMap, nil +} diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index eab99aea..7e7ea8d4 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -107,12 +107,12 @@ func CopyDir( return err } } else { - fileContent, err := replaceTemplateVariables(fileSys, srcPath, customInputs) + fileContent, err := ReplaceTemplateVariables(fileSys, srcPath, customInputs) if err != nil { return err } - if err = checkAllVariablesSubstituted(string(fileContent)); err != nil { + if err = CheckAllVariablesSubstituted(string(fileContent)); err != nil { return fmt.Errorf("error substituting file %s: %w", srcPath, err) } @@ -131,7 +131,7 @@ If any draft variables are found, an error is returned. Draft variables are defined as a string of non-whitespace characters starting with a non-period character wrapped in double curly braces. The non-period first character constraint is used to avoid matching helm template functions. */ -func checkAllVariablesSubstituted(fileContent string) error { +func CheckAllVariablesSubstituted(fileContent string) error { if unsubstitutedVars := draftVariableRegex.FindAllString(fileContent, -1); len(unsubstitutedVars) > 0 { unsubstitutedVarsString := strings.Join(unsubstitutedVars, ", ") return fmt.Errorf("unsubstituted variable: %s", unsubstitutedVarsString) @@ -139,7 +139,7 @@ func checkAllVariablesSubstituted(fileContent string) error { return nil } -func replaceTemplateVariables(fileSys fs.FS, srcPath string, customInputs map[string]string) ([]byte, error) { +func ReplaceTemplateVariables(fileSys fs.FS, srcPath string, customInputs map[string]string) ([]byte, error) { file, err := fs.ReadFile(fileSys, srcPath) if err != nil { return nil, err diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 9dbac56e..2ce38d19 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -31,45 +31,38 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st inputs := make(map[string]string) - for _, customPrompt := range config.Variables { - promptVariableName := customPrompt.Name - if _, ok := skipMap[promptVariableName]; ok { - log.Debugf("Skipping prompt for %s", promptVariableName) + for name, variable := range config.Variables { + if val, ok := skipMap[name]; ok && val != "" { + log.Debugf("Skipping prompt for %s", name) continue } - if GetIsPromptDisabled(customPrompt.Name, config.VariableDefaults) { - log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", promptVariableName) - noPromptDefaultValue := GetVariableDefaultValue(promptVariableName, config.VariableDefaults, inputs) + + if variable.IsPromptDisabled { + log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", name) + noPromptDefaultValue := GetVariableDefaultValue(name, variable, inputs) if noPromptDefaultValue == "" { - return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", promptVariableName) + return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", name) } - log.Debugf("Using default value %s for %s", noPromptDefaultValue, promptVariableName) - inputs[promptVariableName] = noPromptDefaultValue + log.Debugf("Using default value %s for %s", noPromptDefaultValue, name) + inputs[name] = noPromptDefaultValue continue } - log.Debugf("constructing prompt for: %s", promptVariableName) - if customPrompt.VarType == "bool" { - input, err := RunBoolPrompt(customPrompt, Stdin, Stdout) + log.Debugf("constructing prompt for: %s", name) + if variable.Type == "bool" { + input, err := RunBoolPrompt(variable, Stdin, Stdout) if err != nil { return nil, err } - inputs[promptVariableName] = input + inputs[name] = input } else { - defaultValue := GetVariableDefaultValue(promptVariableName, config.VariableDefaults, inputs) + defaultValue := GetVariableDefaultValue(name, variable, inputs) - stringInput, err := RunDefaultableStringPrompt(customPrompt, defaultValue, nil, Stdin, Stdout) + stringInput, err := RunDefaultableStringPrompt(variable, defaultValue, nil, Stdin, Stdout) if err != nil { return nil, err } - inputs[promptVariableName] = stringInput - } - } - - // Substitute the default value for variables where the user didn't enter anything - for _, variableDefault := range config.VariableDefaults { - if inputs[variableDefault.Name] == "" { - inputs[variableDefault.Name] = variableDefault.Value + inputs[name] = stringInput } } @@ -77,28 +70,17 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st } // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal VariableDefault.Value in that order. -func GetVariableDefaultValue(variableName string, variableDefaults []config.BuilderVarDefault, inputs map[string]string) string { +func GetVariableDefaultValue(variableName string, variable config.BuilderVar, inputs map[string]string) string { defaultValue := "" - for _, variableDefault := range variableDefaults { - if variableDefault.Name == variableName { - defaultValue = variableDefault.Value - log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) - if variableDefault.ReferenceVar != "" && inputs[variableDefault.ReferenceVar] != "" { - defaultValue = inputs[variableDefault.ReferenceVar] - log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variableDefault.ReferenceVar) - } - } - } - return defaultValue -} -func GetIsPromptDisabled(variableName string, variableDefaults []config.BuilderVarDefault) bool { - for _, variableDefault := range variableDefaults { - if variableDefault.Name == variableName { - return variableDefault.IsPromptDisabled - } + defaultValue = variable.Value + log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) + if variable.ReferenceVar != "" && inputs[variable.ReferenceVar] != "" { + defaultValue = inputs[variable.ReferenceVar] + log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variable.ReferenceVar) } - return false + + return defaultValue } func RunBoolPrompt(customPrompt config.BuilderVar, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) { diff --git a/pkg/workflows/workflows.go b/pkg/workflows/workflows.go index 1bc4b851..0d07a6e2 100644 --- a/pkg/workflows/workflows.go +++ b/pkg/workflows/workflows.go @@ -20,6 +20,7 @@ import ( "github.com/Azure/draft/pkg/embedutils" "github.com/Azure/draft/pkg/osutil" "github.com/Azure/draft/pkg/templatewriter" + "github.com/Azure/draft/template" ) const ( @@ -187,3 +188,31 @@ func (w *Workflows) CreateWorkflowFiles(deployType string, customInputs map[stri return nil } + +func GenerateWorkflowBytes(draftConfig *config.DraftConfig, deployType string) ([]byte, error) { + envArgs, err := draftConfig.VariableMap() + if err != nil { + return nil, fmt.Errorf("get variable map: %w", err) + } + var srcPath string + + switch deployType { + case "helm": + srcPath = "workflow/helm/.github/workflows/azure-kubernetes-service-helm.yml" + case "manifests": + srcPath = "workflow/manifests/.github/workflows/azure-kubernetes-service.yml" + default: + return nil, errors.New("unsupported deploy type") + } + + workflowBytes, err := osutil.ReplaceTemplateVariables(template.Workflows, srcPath, envArgs) + if err != nil { + return nil, fmt.Errorf("replace template variables: %w", err) + } + + if err = osutil.CheckAllVariablesSubstituted(string(workflowBytes)); err != nil { + return nil, fmt.Errorf("check all variables substituted: %w", err) + } + + return workflowBytes, nil +} diff --git a/template/addons/azure/webapp_routing/draft.yaml b/template/addons/azure/webapp_routing/draft.yaml index 37361578..9e1f04c2 100644 --- a/template/addons/azure/webapp_routing/draft.yaml +++ b/template/addons/azure/webapp_routing/draft.yaml @@ -1,16 +1,14 @@ variables: - - name: "ingress-tls-cert-keyvault-uri" + ingress-tls-cert-keyvault-uri: description: "the keyvault uri for the tls certificate" - - name: "ingress-use-osm-mtls" + ingress-use-osm-mtls: description: "use open service mesh mutual-tls" type: "bool" - - name: "ingress-host" + ingress-host: description: "specify the host of the ingress resource" - - name: "GENERATORLABEL" + GENERATORLABEL: + default: "draft" description: "the label to identify who generated the resource" -variableDefaults: - - name: "GENERATORLABEL" - value: "draft" disablePrompt: true references: service: diff --git a/template/deployments/helm/draft.yaml b/template/deployments/helm/draft.yaml index fe569d50..0c68354e 100644 --- a/template/deployments/helm/draft.yaml +++ b/template/deployments/helm/draft.yaml @@ -1,30 +1,23 @@ variables: - - name: "PORT" + PORT: + default: 80 description: "the port exposed in the application" - - name: "APPNAME" + APPNAME: description: "the name of the application" - - name: "SERVICEPORT" + SERVICEPORT: description: "the port the service uses to make the application accessible from outside the cluster" - - name: "NAMESPACE" + referenceVar: "PORT" + NAMESPACE: + default: default description: " the namespace to place new resources in" - - name: "IMAGENAME" + IMAGENAME: description: "the name of the image to use in the deployment" - - name: "IMAGETAG" - description: "the tag of the image to use in the deployment" - - name: "GENERATORLABEL" - description: "the label to identify who generated the resource" -variableDefaults: - - name: "PORT" - value: 80 - - name: "SERVICEPORT" - referenceVar: "PORT" - - name: "NAMESPACE" - value: default - - name: "IMAGENAME" referenceVar: "APPNAME" - - name: "IMAGETAG" - value: "latest" - disablePrompt: true - - name: "GENERATORLABEL" - value: "draft" + IMAGETAG: + default: "latest" + description: "the tag of the image to use in the deployment" disablePrompt: true + GENERATORLABEL: + default: "draft" + description: "the label to identify who generated the resource" + disablePrompt: true \ No newline at end of file diff --git a/template/deployments/kustomize/draft.yaml b/template/deployments/kustomize/draft.yaml index 487550d9..b22534b6 100644 --- a/template/deployments/kustomize/draft.yaml +++ b/template/deployments/kustomize/draft.yaml @@ -1,30 +1,23 @@ variables: - - name: "PORT" + PORT: + default: 80 description: "the port exposed in the application" - - name: "APPNAME" + APPNAME: description: "the name of the application" - - name: "SERVICEPORT" + SERVICEPORT: description: "the port the service uses to make the application accessible from outside the cluster" - - name: "NAMESPACE" + referenceVar: "PORT" + NAMESPACE: + default: default description: " the namespace to place new resources in" - - name: "IMAGENAME" + IMAGENAME: description: "the name of the image to use in the deployment" - - name: "IMAGETAG" - description: "the tag of the image to use in the deployment" - - name: "GENERATORLABEL" - description: "the label to identify who generated the resource" -variableDefaults: - - name: "PORT" - value: 80 - - name: "SERVICEPORT" - referenceVar: "PORT" - - name: "NAMESPACE" - value: default - - name: "IMAGENAME" referenceVar: "APPNAME" - - name: "IMAGETAG" - value: "latest" + IMAGETAG: + default: "latest" + description: "the tag of the image to use in the deployment" disablePrompt: true - - name: "GENERATORLABEL" - value: "draft" + GENERATORLABEL: + default: "draft" + description: "the label to identify who generated the resource" disablePrompt: true \ No newline at end of file diff --git a/template/deployments/manifests/draft.yaml b/template/deployments/manifests/draft.yaml index 487550d9..b22534b6 100644 --- a/template/deployments/manifests/draft.yaml +++ b/template/deployments/manifests/draft.yaml @@ -1,30 +1,23 @@ variables: - - name: "PORT" + PORT: + default: 80 description: "the port exposed in the application" - - name: "APPNAME" + APPNAME: description: "the name of the application" - - name: "SERVICEPORT" + SERVICEPORT: description: "the port the service uses to make the application accessible from outside the cluster" - - name: "NAMESPACE" + referenceVar: "PORT" + NAMESPACE: + default: default description: " the namespace to place new resources in" - - name: "IMAGENAME" + IMAGENAME: description: "the name of the image to use in the deployment" - - name: "IMAGETAG" - description: "the tag of the image to use in the deployment" - - name: "GENERATORLABEL" - description: "the label to identify who generated the resource" -variableDefaults: - - name: "PORT" - value: 80 - - name: "SERVICEPORT" - referenceVar: "PORT" - - name: "NAMESPACE" - value: default - - name: "IMAGENAME" referenceVar: "APPNAME" - - name: "IMAGETAG" - value: "latest" + IMAGETAG: + default: "latest" + description: "the tag of the image to use in the deployment" disablePrompt: true - - name: "GENERATORLABEL" - value: "draft" + GENERATORLABEL: + default: "draft" + description: "the label to identify who generated the resource" disablePrompt: true \ No newline at end of file diff --git a/template/dockerfiles/clojure/draft.yaml b/template/dockerfiles/clojure/draft.yaml index d5a0b059..2ce6d5db 100644 --- a/template/dockerfiles/clojure/draft.yaml +++ b/template/dockerfiles/clojure/draft.yaml @@ -1,14 +1,11 @@ language: clojure displayName: Clojure variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "8-jdk-alpine" description: "the version of openjdk that the application uses" - exampleValues: ["8-jdk-alpine","11-jdk-alpine","17-jdk-alpine","19-jdk-alpine"] -variableDefaults: - - name: "VERSION" - value: "8-jdk-alpine" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["8-jdk-alpine","11-jdk-alpine","17-jdk-alpine","19-jdk-alpine"] \ No newline at end of file diff --git a/template/dockerfiles/csharp/draft.yaml b/template/dockerfiles/csharp/draft.yaml index 4f0cccda..1672144e 100644 --- a/template/dockerfiles/csharp/draft.yaml +++ b/template/dockerfiles/csharp/draft.yaml @@ -1,15 +1,12 @@ language: csharp displayName: C# variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "5.0" description: "the dotnet SDK version" type: float - exampleValues: ["3.1","4.0","5.0","6.0"] -variableDefaults: - - name: "VERSION" - value: "5.0" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["3.1","4.0","5.0","6.0"] \ No newline at end of file diff --git a/template/dockerfiles/erlang/draft.yaml b/template/dockerfiles/erlang/draft.yaml index d117a689..7b9b319a 100644 --- a/template/dockerfiles/erlang/draft.yaml +++ b/template/dockerfiles/erlang/draft.yaml @@ -4,19 +4,16 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "BUILDERVERSION" + BUILDERVERSION: + default: "24.2-alpine" description: "the version of erlang used during the builder stage to generate the executable" exampleValues: ["24.2-alpine"] - - name: "VERSION" + VERSION: + default: "3.15" description: "the version of alpine used by the application" exampleValues: ["3.15"] -variableDefaults: - - name: "BUILDERVERSION" - value: "24.2-alpine" - - name: "VERSION" - value: "3.15" - - name: "PORT" - value: "80" \ No newline at end of file + \ No newline at end of file diff --git a/template/dockerfiles/go/draft.yaml b/template/dockerfiles/go/draft.yaml index fc6948c8..d1be5724 100644 --- a/template/dockerfiles/go/draft.yaml +++ b/template/dockerfiles/go/draft.yaml @@ -4,14 +4,11 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "1.18" description: "the version of go used by the application" - exampleValues: ["1.16", "1.17", "1.18", "1.19"] -variableDefaults: - - name: "VERSION" - value: "1.18" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["1.16", "1.17", "1.18", "1.19"] \ No newline at end of file diff --git a/template/dockerfiles/gomodule/draft.yaml b/template/dockerfiles/gomodule/draft.yaml index 9477a527..3fb4c382 100644 --- a/template/dockerfiles/gomodule/draft.yaml +++ b/template/dockerfiles/gomodule/draft.yaml @@ -4,14 +4,11 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" - type: int - - name: "VERSION" + type: int + VERSION: + default: "1.18" description: "the version of go used by the application" - exampleValues: ["1.16", "1.17", "1.18", "1.19"] -variableDefaults: - - name: "VERSION" - value: "1.18" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["1.16", "1.17", "1.18", "1.19"] \ No newline at end of file diff --git a/template/dockerfiles/gradle/draft.yaml b/template/dockerfiles/gradle/draft.yaml index 166f1dc3..2f9c8e4e 100644 --- a/template/dockerfiles/gradle/draft.yaml +++ b/template/dockerfiles/gradle/draft.yaml @@ -4,19 +4,15 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" - description: "the port exposed in the application" - type: int - - name: "BUILDERVERSION" + BUILDERVERSION: + default: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] - - name: "VERSION" + PORT: + default: "80" + description: "the port exposed in the application" + type: int + VERSION: + default: "21-jre" description: "the java version used by the application" - exampleValues: ["11-jre","17-jre","19-jre","21-jre"] -variableDefaults: - - name: "BUILDERVERSION" - value: "jdk21" - - name: "VERSION" - value: "21-jre" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["11-jre","17-jre","19-jre","21-jre"] \ No newline at end of file diff --git a/template/dockerfiles/gradlew/draft.yaml b/template/dockerfiles/gradlew/draft.yaml index 166f1dc3..511be226 100644 --- a/template/dockerfiles/gradlew/draft.yaml +++ b/template/dockerfiles/gradlew/draft.yaml @@ -4,19 +4,15 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "BUILDERVERSION" + BUILDERVERSION: + default: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] - - name: "VERSION" + VERSION: + default: "21-jre" description: "the java version used by the application" - exampleValues: ["11-jre","17-jre","19-jre","21-jre"] -variableDefaults: - - name: "BUILDERVERSION" - value: "jdk21" - - name: "VERSION" - value: "21-jre" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["11-jre","17-jre","19-jre","21-jre"] \ No newline at end of file diff --git a/template/dockerfiles/java/draft.yaml b/template/dockerfiles/java/draft.yaml index 0df09bca..5797546b 100644 --- a/template/dockerfiles/java/draft.yaml +++ b/template/dockerfiles/java/draft.yaml @@ -4,19 +4,15 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "BUILDERVERSION" + BUILDERVERSION: + default: "3" description: "the version of maven used during the builder stage to generate the executable" exampleValues: ["3-eclipse-temurin-11", "3-eclipse-temurin-17", "3-eclipse-temurin-21", "3 (jdk-21)"] - - name: "VERSION" + VERSION: + default: "21-jre" description: "the java version used by the application" - exampleValues: ["11-jre","17-jre","19-jre","21-jre"] -variableDefaults: - - name: "BUILDERVERSION" - value: "3" - - name: "VERSION" - value: "21-jre" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["11-jre","17-jre","19-jre","21-jre"] \ No newline at end of file diff --git a/template/dockerfiles/javascript/draft.yaml b/template/dockerfiles/javascript/draft.yaml index fc9bd44e..dcce8adb 100644 --- a/template/dockerfiles/javascript/draft.yaml +++ b/template/dockerfiles/javascript/draft.yaml @@ -4,14 +4,11 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "14" description: "the version of node used in the application" - exampleValues: ["10.16.3", "12.16.3", "14.15.4"] -variableDefaults: - - name: "VERSION" - value: "14" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["10.16.3", "12.16.3", "14.15.4"] \ No newline at end of file diff --git a/template/dockerfiles/php/draft.yaml b/template/dockerfiles/php/draft.yaml index d72f2e0c..4b3db86c 100644 --- a/template/dockerfiles/php/draft.yaml +++ b/template/dockerfiles/php/draft.yaml @@ -4,19 +4,15 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "BUILDERVERSION" + BUILDERVERSION: + default: "1" description: "the version of composer installed during the build stage to be used by the application" exampleValues: ["1"] - - name: "VERSION" + VERSION: + default: "7.1-apache" description: "the version of php used by the application" - exampleValues: ["7.1-apache"] -variableDefaults: - - name: "BUILDERVERSION" - value: "1" - - name: "VERSION" - value: "7.1-apache" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["7.1-apache"] \ No newline at end of file diff --git a/template/dockerfiles/python/draft.yaml b/template/dockerfiles/python/draft.yaml index 7d361ed1..e9615b87 100644 --- a/template/dockerfiles/python/draft.yaml +++ b/template/dockerfiles/python/draft.yaml @@ -4,20 +4,16 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "3" description: "the version of python used by the application" exampleValues: ["3.9", "3.8", "3.7", "3.6"] - - name: "ENTRYPOINT" + ENTRYPOINT: + default: "app.py" description: "the entrypoint file of the repository" type: string - exampleValues: ["app.py", "main.py"] -variableDefaults: - - name: "VERSION" - value: "3" - - name: "PORT" - value: "80" - - name: "ENTRYPOINT" - value: "app.py" + exampleValues: ["app.py", "main.py"] \ No newline at end of file diff --git a/template/dockerfiles/ruby/draft.yaml b/template/dockerfiles/ruby/draft.yaml index dd2ee4d8..ed165f2f 100644 --- a/template/dockerfiles/ruby/draft.yaml +++ b/template/dockerfiles/ruby/draft.yaml @@ -4,14 +4,11 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "3.1.2" description: "the version of ruby used by the application" - exampleValues: ["3.1.2", "2.6", "2.5", "2.4"] -variableDefaults: - - name: "VERSION" - value: "3.1.2" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["3.1.2", "2.6", "2.5", "2.4"] \ No newline at end of file diff --git a/template/dockerfiles/rust/draft.yaml b/template/dockerfiles/rust/draft.yaml index 00848d00..e76dff7a 100644 --- a/template/dockerfiles/rust/draft.yaml +++ b/template/dockerfiles/rust/draft.yaml @@ -4,14 +4,11 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "1.70.0" description: "the version of rust used by the application" - exampleValues: ["1.70.0","1.65.0", "1.60", "1.54", "1.53"] -variableDefaults: - - name: "VERSION" - value: "1.70.0" - - name: "PORT" - value: "80" + exampleValues: ["1.70.0","1.65.0", "1.60", "1.54", "1.53"] \ No newline at end of file diff --git a/template/dockerfiles/swift/draft.yaml b/template/dockerfiles/swift/draft.yaml index 1780f683..1a984afb 100644 --- a/template/dockerfiles/swift/draft.yaml +++ b/template/dockerfiles/swift/draft.yaml @@ -4,14 +4,11 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "PORT" + PORT: + default: "80" description: "the port exposed in the application" type: int - - name: "VERSION" + VERSION: + default: "5.5" description: "the version of swift used by the application" - exampleValues: ["5.2","5.5"] -variableDefaults: - - name: "VERSION" - value: "5.5" - - name: "PORT" - value: "80" \ No newline at end of file + exampleValues: ["5.2","5.5"] \ No newline at end of file diff --git a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml index 93613263..d5d878dd 100644 --- a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml +++ b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml @@ -32,7 +32,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: Build and deploy an app to AKS with Helm +name: {{WORKFLOWNAME}} on: push: @@ -40,14 +40,19 @@ on: workflow_dispatch: env: + ACR_RESOURCE_GROUP: {{ACRRESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} - RESOURCE_GROUP: {{RESOURCEGROUP}} + CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} + DOCKER_FILE: {{DOCKERFILE}} + BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} CHART_PATH: {{CHARTPATH}} CHART_OVERRIDE_PATH: {{CHARTOVERRIDEPATH}} - BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} - + CHART_OVERRIDES: {{CHARTOVERRIDES}} + NAMESPACE: {{NAMESPACE}} + PRIVATE_CLUSTER: {{PRIVATECLUSTER}} + jobs: buildImage: permissions: @@ -69,7 +74,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} . + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -99,7 +104,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.RESOURCE_GROUP }} + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -111,8 +116,7 @@ jobs: renderEngine: "helm" helmChart: ${{ env.CHART_PATH }} overrideFiles: ${{ env.CHART_OVERRIDE_PATH }} - overrides: | - replicas:2 + overrides: ${{ env.CHART_OVERRIDES }} helm-version: "latest" id: bake @@ -124,3 +128,5 @@ jobs: manifests: ${{ steps.bake.outputs.manifestsBundle }} images: | ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + namespace: ${{ env.NAMESPACE }} + private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index 7bb3aecd..f093135e 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -1,22 +1,51 @@ variables: - - name: "AZURECONTAINERREGISTRY" + WORKFLOWNAME: + default: "Build and deploy an app to AKS with Helm" + description: "the name of the workflow" + BRANCHNAME: + description: "the Github branch to automatically deploy from" + resource: "ghBranch" + ACRRESOURCEGROUP: + description: "the ACR resource group" + resource: "azResourceGroup" + AZURECONTAINERREGISTRY: description: "the Azure container registry name" - - name: "CONTAINERNAME" + resource: "azContainerRegistry" + CONTAINERNAME: description: "the container image name" - - name: "RESOURCEGROUP" - description: "the Azure resource group of your AKS cluster" - - name: "CLUSTERNAME" + resource: "containerName" + CLUSTERRESOURCEGROUP: + description: "the AKS cluster resource group" + resource: "azResourceGroup" + CLUSTERNAME: description: "the AKS cluster name" - - name: "BRANCHNAME" - description: "the Github branch to automatically deploy from" - - name: "BUILDCONTEXTPATH" + resource: "azClusterName" + DOCKERFILE: + description: "the path to the Dockerfile" + resource: "dir" + BUILDCONTEXTPATH: + default: "." description: "the path to the Docker build context" -variableDefaults: - - name: "CHARTPATH" - value: "./charts" + resource: "dir" + CHARTPATH: + default: "./charts" + description: "the path to the Helm chart" + disablePrompt: true + resource: "dir" + CHARTOVERRIDEPATH: + default: "./charts/production.yaml" + description: "the path to the Helm chart override file" disablePrompt: true - - name: "CHARTOVERRIDEPATH" - value: "./charts/production.yaml" + resource: "dir" + CHARTOVERRIDES: + default: "replicas:2" + description: "the Helm chart overrides" disablePrompt: true - - name: "BUILDCONTEXTPATH" - value: "." \ No newline at end of file + NAMESPACE: + default: "default" + description: "the Kubernetes namespace" + PRIVATECLUSTER: + default: "false" + description: "set to true if the AKS cluster is private" + type: "bool" + \ No newline at end of file diff --git a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml index 839ad953..33bbbfd1 100644 --- a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml +++ b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml @@ -31,7 +31,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: Build and deploy an app to AKS with Kustomize +name: {{WORKFLOWNAME}} on: push: @@ -39,12 +39,16 @@ on: workflow_dispatch: env: + ACR_RESOURCE_GROUP: {{RESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} - RESOURCE_GROUP: {{RESOURCEGROUP}} + CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} KUSTOMIZE_PATH: {{KUSTOMIZEPATH}} + DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} + NAMESPACE: {{NAMESPACE}} + PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -67,7 +71,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} . + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -97,7 +101,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.RESOURCE_GROUP }} + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -119,3 +123,5 @@ jobs: manifests: ${{ steps.bake.outputs.manifestsBundle }} images: | ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + namespace: ${{ env.NAMESPACE }} + private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index f763eff3..2d152417 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -1,19 +1,40 @@ variables: - - name: "AZURECONTAINERREGISTRY" + WORKFLOWNAME: + default: "Build and deploy an app to AKS with Helm" + description: "the name of the workflow" + BRANCHNAME: + description: "the Github branch to automatically deploy from" + resource: "ghBranch" + ACRRESOURCEGROUP: + description: "the ACR resource group" + resource: "azResourceGroup" + AZURECONTAINERREGISTRY: description: "the Azure container registry name" - - name: "CONTAINERNAME" + resource: "azContainerRegistry" + CONTAINERNAME: description: "the container image name" - - name: "RESOURCEGROUP" - description: "the Azure resource group of your AKS cluster" - - name: "CLUSTERNAME" + resource: "containerName" + CLUSTERRESOURCEGROUP: + description: "the AKS cluster resource group" + resource: "azResourceGroup" + CLUSTERNAME: description: "the AKS cluster name" - - name: "BRANCHNAME" - description: "the Github branch to automatically deploy from" - - name: "BUILDCONTEXTPATH" - description: "the path to the Docker build context" -variableDefaults: - - name: "KUSTOMIZEPATH" - value: "./overlays/production" + resource: "azClusterName" + KUSTOMIZEPATH: + default: "./overlays/production" + description: "the path to the Kustomize directory" disablePrompt: true - - name: "BUILDCONTEXTPATH" - value: "." + resource: "dir" + DOCKERFILE: + description: "the path to the Dockerfile" + resource: "dir" + BUILDCONTEXTPATH: + default: "." + description: "the path to the Docker build context" + NAMESPACE: + default: "default" + description: "the Kubernetes namespace" + PRIVATECLUSTER: + default: "false" + description: "set to true if the AKS cluster is private" + type: "bool" \ No newline at end of file diff --git a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml index 4528cfda..cded5a1d 100644 --- a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml +++ b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml @@ -27,7 +27,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: Build and deploy an app to AKS +name: {{WORKFLOWNAME}} on: push: @@ -35,12 +35,16 @@ on: workflow_dispatch: env: + ACR_RESOURCE_GROUP: {{ACRRESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} - RESOURCE_GROUP: {{RESOURCEGROUP}} + CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} DEPLOYMENT_MANIFEST_PATH: {{DEPLOYMENTMANIFESTPATH}} + DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} + NAMESPACE: {{NAMESPACE}} + PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -63,7 +67,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} . + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -93,7 +97,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.RESOURCE_GROUP }} + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -106,3 +110,6 @@ jobs: manifests: ${{ env.DEPLOYMENT_MANIFEST_PATH }} images: | ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + namespace: ${{ env.NAMESPACE }} + private-cluster: ${{ env.PRIVATE_CLUSTER }} + \ No newline at end of file diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index a51756a1..12821ee9 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -1,19 +1,40 @@ variables: - - name: "AZURECONTAINERREGISTRY" + WORKFLOWNAME: + default: "Build and deploy an app to AKS" + description: "the name of the workflow" + BRANCHNAME: + description: "the Github branch to automatically deploy from" + resource: "ghBranch" + ACRRESOURCEGROUP: + description: "the ACR resource group" + resource: "azResourceGroup" + AZURECONTAINERREGISTRY: description: "the Azure container registry name" - - name: "CONTAINERNAME" + resource: "azContainerRegistry" + CONTAINERNAME: description: "the container image name" - - name: "RESOURCEGROUP" - description: "the Azure resource group of your AKS cluster" - - name: "CLUSTERNAME" + resource: "containerName" + CLUSTERRESOURCEGROUP: + description: "the AKS cluster resource group" + resource: "azResourceGroup" + CLUSTERNAME: description: "the AKS cluster name" - - name: "BRANCHNAME" - description: "the Github branch to automatically deploy from" - - name: "BUILDCONTEXTPATH" - description: "the path to the Docker build context" -variableDefaults: - - name: "DEPLOYMENTMANIFESTPATH" - value: "./manifests" + resource: "azClusterName" + DEPLOYMENTMANIFESTPATH: + default: "./manifests" + description: "the path to the Kubernetes deployment manifest" disablePrompt: true - - name: "BUILDCONTEXTPATH" - value: "." + resource: "dir" + DOCKERFILE: + description: "the path to the Dockerfile" + resource: "dir" + BUILDCONTEXTPATH: + default: "." + description: "the path to the Docker build context" + NAMESPACE: + default: "default" + description: "the Kubernetes namespace" + PRIVATECLUSTER: + default: "false" + description: "set to true if the AKS cluster is private" + type: "bool" \ No newline at end of file From 65f9520636e9b9548d5d393f4aa5bb15ece8c96a Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Tue, 18 Jun 2024 14:00:05 -0700 Subject: [PATCH 07/44] updated the sanitize function --- pkg/prompts/prompts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index e4514166..ca0ef52a 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -325,12 +325,12 @@ func sanitizeAppName(name string) string { if sanitized == "" { sanitized = defaultAppName } else { - // Trim leading and trailing '-', '_', '.' - sanitized = strings.Trim(sanitized, "-._") // Ensure the length does not exceed 63 characters if len(sanitized) > 63 { sanitized = sanitized[:63] } + // Trim leading and trailing '-', '_', '.' + sanitized = strings.Trim(sanitized, "-._") } return sanitized } From c289515cc38a3877dde61c0505a26228bae7ecc6 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Wed, 19 Jun 2024 13:25:21 -0400 Subject: [PATCH 08/44] refactored tests for new config --- cmd/create_test.go | 20 +++---- cmd/setup-gh.go | 4 +- pkg/osutil/osutil_test.go | 2 +- pkg/prompts/prompts.go | 4 +- pkg/prompts/prompts_test.go | 110 ++++++++++++++---------------------- pkg/workflows/workflows.go | 2 +- 6 files changed, 57 insertions(+), 85 deletions(-) diff --git a/cmd/create_test.go b/cmd/create_test.go index 99c96f87..f8d70b90 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -142,33 +142,29 @@ func TestInitConfig(t *testing.T) { } func TestValidateConfigInputsToPromptsPass(t *testing.T) { - required := []config.BuilderVar{ - {Name: "REQUIRED_PROVIDED"}, - {Name: "REQUIRED_DEFAULTED"}, + required := map[string]config.BuilderVar{ + "REQUIRED_PROVIDED": {}, + "REQUIRED_DEFAULTED": {DefaultValue: "DEFAULT_VALUE"}, } provided := []UserInputs{ {Name: "REQUIRED_PROVIDED", Value: "PROVIDED_VALUE"}, } - defaults := []config.BuilderVarDefault{ - {Name: "REQUIRED_DEFAULTED", Value: "DEFAULT_VALUE"}, - } - vars, err := validateConfigInputsToPrompts(required, provided, defaults) + vars, err := validateConfigInputsToPrompts(required, provided) assert.True(t, err == nil) assert.Equal(t, vars["REQUIRED_DEFAULTED"], "DEFAULT_VALUE") } func TestValidateConfigInputsToPromptsMissing(t *testing.T) { - required := []config.BuilderVar{ - {Name: "REQUIRED_PROVIDED"}, - {Name: "REQUIRED_MISSING"}, + required := map[string]config.BuilderVar{ + "REQUIRED_PROVIDED": {}, + "REQUIRED_MISSING": {}, } provided := []UserInputs{ {Name: "REQUIRED_PROVIDED"}, } - defaults := []config.BuilderVarDefault{} - _, err := validateConfigInputsToPrompts(required, provided, defaults) + _, err := validateConfigInputsToPrompts(required, provided) assert.NotNil(t, err) } diff --git a/cmd/setup-gh.go b/cmd/setup-gh.go index ae31625b..d4862177 100644 --- a/cmd/setup-gh.go +++ b/cmd/setup-gh.go @@ -87,7 +87,7 @@ func fillSetUpConfig(sc *providers.SetUpCmd) error { return fmt.Errorf("getting subscription labels: %w", err) } - sc.SubscriptionID, err = GetAzSubscriptionId(subLabels, currentSub) + sc.SubscriptionID, err = getAzSubscriptionId(subLabels, currentSub) if err != nil { return fmt.Errorf("getting subscription ID: %w", err) } @@ -223,7 +223,7 @@ func getCloudProvider() string { return selectResponse } -func GetAzSubscriptionId(subLabels []providers.SubLabel, currentSub providers.SubLabel) (string, error) { +func getAzSubscriptionId(subLabels []providers.SubLabel, currentSub providers.SubLabel) (string, error) { subLabel, err := prompts.Select("Please choose the subscription ID you would like to use", subLabels, &prompts.SelectOpt[providers.SubLabel]{ Field: func(subLabel providers.SubLabel) string { return subLabel.Name + " (" + subLabel.ID + ")" diff --git a/pkg/osutil/osutil_test.go b/pkg/osutil/osutil_test.go index ed108062..8536a77a 100644 --- a/pkg/osutil/osutil_test.go +++ b/pkg/osutil/osutil_test.go @@ -110,7 +110,7 @@ func TestAllVariablesSubstituted(t *testing.T) { for _, test := range tests { t.Run(test.String, func(t *testing.T) { - err := checkAllVariablesSubstituted(test.String) + err := CheckAllVariablesSubstituted(test.String) didError := err != nil assert.Equal(t, test.ExpectError, didError) }) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 2ce38d19..50163862 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -69,11 +69,11 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st return inputs, nil } -// GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal VariableDefault.Value in that order. +// GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal Variable.DefaultValue in that order. func GetVariableDefaultValue(variableName string, variable config.BuilderVar, inputs map[string]string) string { defaultValue := "" - defaultValue = variable.Value + defaultValue = variable.DefaultValue log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) if variable.ReferenceVar != "" && inputs[variable.ReferenceVar] != "" { defaultValue = inputs[variable.ReferenceVar] diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index 689ead70..d6deb972 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -9,42 +9,39 @@ import ( func TestGetVariableDefaultValue(t *testing.T) { tests := []struct { - testName string - variableName string - variableDefaults []config.BuilderVarDefault - inputs map[string]string - want string + testName string + variableName string + variables map[string]config.BuilderVar + inputs map[string]string + want string }{ { testName: "basicLiteralExtractDefault", variableName: "var1", - variableDefaults: []config.BuilderVarDefault{ - { - Name: "var1", - Value: "default-value-1", + variables: map[string]config.BuilderVar{ + "var1": { + DefaultValue: "default-value-1", }, - { - Name: "var2", - Value: "default-value-2", + "var2": { + DefaultValue: "default-value-2", }, }, inputs: map[string]string{}, want: "default-value-1", }, { - testName: "noDefaultIsEmptyString", - variableName: "var1", - variableDefaults: []config.BuilderVarDefault{}, - inputs: map[string]string{}, - want: "", + testName: "noDefaultIsEmptyString", + variableName: "var1", + variables: map[string]config.BuilderVar{}, + inputs: map[string]string{}, + want: "", }, { testName: "referenceTakesPrecedenceOverLiteral", variableName: "var1", - variableDefaults: []config.BuilderVarDefault{ - { - Name: "var1", - Value: "not-this-value", + variables: map[string]config.BuilderVar{ + "var1": { + DefaultValue: "not-this-value", ReferenceVar: "var2", }, }, @@ -55,14 +52,13 @@ func TestGetVariableDefaultValue(t *testing.T) { }, { testName: "forwardReferencesAreIgnored", variableName: "beforeVar", - variableDefaults: []config.BuilderVarDefault{ - { - Name: "beforeVar", - Value: "before-default-value", + variables: map[string]config.BuilderVar{ + "beforeVar": { + DefaultValue: "before-default-value", ReferenceVar: "afterVar", - }, { - Name: "afterVar", - Value: "not-this-value", + }, + "afterVar": { + DefaultValue: "not-this-value", }, }, inputs: map[string]string{}, @@ -71,7 +67,7 @@ func TestGetVariableDefaultValue(t *testing.T) { } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - if got := GetVariableDefaultValue(tt.variableName, tt.variableDefaults, tt.inputs); got != tt.want { + if got := GetVariableDefaultValue(tt.variableName, tt.variables[tt.variableName], tt.inputs); got != tt.want { t.Errorf("GetVariableDefaultValue() = %v, want %v", got, tt.want) } }) @@ -90,7 +86,6 @@ func TestRunStringPrompt(t *testing.T) { { testName: "basicPrompt", prompt: config.BuilderVar{ - Name: "var1", Description: "var1 description", }, userInputs: []string{"value-1\n"}, @@ -101,7 +96,6 @@ func TestRunStringPrompt(t *testing.T) { { testName: "promptWithDefault", prompt: config.BuilderVar{ - Name: "var1", Description: "var1 description", }, userInputs: []string{"\n"}, @@ -150,16 +144,10 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { { testName: "onlyNoPrompt", config: config.DraftConfig{ - Variables: []config.BuilderVar{ - { - Name: "var1", + Variables: map[string]config.BuilderVar{ + "var1": { + DefaultValue: "defaultValue", Description: "var1 description", - }, - }, - VariableDefaults: []config.BuilderVarDefault{ - { - Name: "var1", - Value: "defaultValue", IsPromptDisabled: true, }, }, @@ -172,36 +160,24 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { }, { testName: "twoPromptTwoNoPrompt", config: config.DraftConfig{ - Variables: []config.BuilderVar{ - { - Name: "var1-no-prompt", + Variables: map[string]config.BuilderVar{ + "var1-no-prompt": { + DefaultValue: "defaultValueNoPrompt1", Description: "var1 has IsPromptDisabled and should skip prompt and use default value", - }, { - Name: "var2-default", - Description: "var2 has a default value and will receive an empty value, so it should use the default value", - }, { - Name: "var3-no-prompt", - Description: "var3 has IsPromptDisabled and should skip prompt and use default value", - }, { - Name: "var4", - Description: "var4 has a default value, but has a value entered, so it should use the entered value", - }, - }, - VariableDefaults: []config.BuilderVarDefault{ - { - Name: "var1-no-prompt", - Value: "defaultValueNoPrompt1", IsPromptDisabled: true, - }, { - Name: "var2-default", - Value: "defaultValue2", - }, { - Name: "var3-no-prompt", - Value: "defaultValueNoPrompt3", + }, + "var2-default": { + DefaultValue: "defaultValue2", + Description: "var2 has a default value and will receive an empty value, so it should use the default value", + }, + "var3-no-prompt": { + DefaultValue: "defaultValueNoPrompt3", + Description: "var3 has IsPromptDisabled and should skip prompt and use default value", IsPromptDisabled: true, - }, { - Name: "var4", - Value: "defaultValue4", + }, + "var4": { + DefaultValue: "defaultValue4", + Description: "var4 has a default value, but has a value entered, so it should use the entered value", }, }, }, diff --git a/pkg/workflows/workflows.go b/pkg/workflows/workflows.go index 0d07a6e2..36df905e 100644 --- a/pkg/workflows/workflows.go +++ b/pkg/workflows/workflows.go @@ -199,7 +199,7 @@ func GenerateWorkflowBytes(draftConfig *config.DraftConfig, deployType string) ( switch deployType { case "helm": srcPath = "workflow/helm/.github/workflows/azure-kubernetes-service-helm.yml" - case "manifests": + case "kube": srcPath = "workflow/manifests/.github/workflows/azure-kubernetes-service.yml" default: return nil, errors.New("unsupported deploy type") From 7400d71446a978ad103cad0f76627edf6a3365d9 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Wed, 19 Jun 2024 14:27:06 -0400 Subject: [PATCH 09/44] handling for Dockerfile envarg --- pkg/config/draftconfig.go | 8 ++++---- pkg/prompts/prompts.go | 2 +- template/workflows/helm/draft.yaml | 1 + template/workflows/kustomize/draft.yaml | 1 + template/workflows/manifests/draft.yaml | 1 + 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 8f087855..5a724d66 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -67,12 +67,12 @@ func (d *DraftConfig) GetNameOverride(path string) string { func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) error { for name, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling - if defaultVal, ok := customConfig[name]; !ok || defaultVal == "" { - if variable.Value == "" { + if val, ok := customConfig[name]; !ok || val == "" { + if variable.DefaultValue == "" && name != "DOCKERFILE" { return errors.New("variable " + name + " has no default value") } - log.Infof("Variable %s defaulting to value %s", name, variable.Value) - customConfig[name] = variable.Value + log.Infof("Variable %s defaulting to value %s", name, variable.DefaultValue) + customConfig[name] = variable.DefaultValue } } diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 50163862..fb56ddeb 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -40,7 +40,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st if variable.IsPromptDisabled { log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", name) noPromptDefaultValue := GetVariableDefaultValue(name, variable, inputs) - if noPromptDefaultValue == "" { + if noPromptDefaultValue == "" && name != "DOCKERFILE" { return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", name) } log.Debugf("Using default value %s for %s", noPromptDefaultValue, name) diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index f093135e..5cb9f372 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -22,6 +22,7 @@ variables: resource: "azClusterName" DOCKERFILE: description: "the path to the Dockerfile" + disablePrompt: true resource: "dir" BUILDCONTEXTPATH: default: "." diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index 2d152417..e0f66c79 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -27,6 +27,7 @@ variables: resource: "dir" DOCKERFILE: description: "the path to the Dockerfile" + disablePrompt: true resource: "dir" BUILDCONTEXTPATH: default: "." diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index 12821ee9..a6df2448 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -27,6 +27,7 @@ variables: resource: "dir" DOCKERFILE: description: "the path to the Dockerfile" + disablePrompt: true resource: "dir" BUILDCONTEXTPATH: default: "." From 3e5576907e07d6f7c1cbe2313792661bea2ce2c8 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Thu, 20 Jun 2024 12:09:12 -0400 Subject: [PATCH 10/44] rolled back changes for PR separation --- pkg/config/draftconfig.go | 1 - pkg/workflows/workflows.go | 29 ------------------- .../azure-kubernetes-service-helm.yml | 16 ++++------ template/workflows/helm/draft.yaml | 27 +---------------- .../azure-kubernetes-service-kustomize.yml | 16 ++++------ template/workflows/kustomize/draft.yaml | 27 ++--------------- .../workflows/azure-kubernetes-service.yml | 14 +++------ template/workflows/manifests/draft.yaml | 27 ++--------------- 8 files changed, 19 insertions(+), 138 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 5a724d66..648824e4 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -26,7 +26,6 @@ type BuilderVar struct { ExampleValues []string `yaml:"exampleValues"` IsPromptDisabled bool `yaml:"disablePrompt"` ReferenceVar string `yaml:"referenceVar"` - ResourceType string `yaml:"resource"` Type string `yaml:"type"` Value string `yaml:"value"` } diff --git a/pkg/workflows/workflows.go b/pkg/workflows/workflows.go index 36df905e..1bc4b851 100644 --- a/pkg/workflows/workflows.go +++ b/pkg/workflows/workflows.go @@ -20,7 +20,6 @@ import ( "github.com/Azure/draft/pkg/embedutils" "github.com/Azure/draft/pkg/osutil" "github.com/Azure/draft/pkg/templatewriter" - "github.com/Azure/draft/template" ) const ( @@ -188,31 +187,3 @@ func (w *Workflows) CreateWorkflowFiles(deployType string, customInputs map[stri return nil } - -func GenerateWorkflowBytes(draftConfig *config.DraftConfig, deployType string) ([]byte, error) { - envArgs, err := draftConfig.VariableMap() - if err != nil { - return nil, fmt.Errorf("get variable map: %w", err) - } - var srcPath string - - switch deployType { - case "helm": - srcPath = "workflow/helm/.github/workflows/azure-kubernetes-service-helm.yml" - case "kube": - srcPath = "workflow/manifests/.github/workflows/azure-kubernetes-service.yml" - default: - return nil, errors.New("unsupported deploy type") - } - - workflowBytes, err := osutil.ReplaceTemplateVariables(template.Workflows, srcPath, envArgs) - if err != nil { - return nil, fmt.Errorf("replace template variables: %w", err) - } - - if err = osutil.CheckAllVariablesSubstituted(string(workflowBytes)); err != nil { - return nil, fmt.Errorf("check all variables substituted: %w", err) - } - - return workflowBytes, nil -} diff --git a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml index d5d878dd..d9291551 100644 --- a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml +++ b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml @@ -32,7 +32,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: {{WORKFLOWNAME}} +name: ""Build and deploy an app to AKS with Helm" on: push: @@ -40,18 +40,14 @@ on: workflow_dispatch: env: - ACR_RESOURCE_GROUP: {{ACRRESOURCEGROUP}} + RESOURCE_GROUP: {{RESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} - CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} - DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} CHART_PATH: {{CHARTPATH}} CHART_OVERRIDE_PATH: {{CHARTOVERRIDEPATH}} CHART_OVERRIDES: {{CHARTOVERRIDES}} - NAMESPACE: {{NAMESPACE}} - PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -74,7 +70,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -104,7 +100,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} + resource-group: ${{ env.RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -127,6 +123,4 @@ jobs: action: deploy manifests: ${{ steps.bake.outputs.manifestsBundle }} images: | - ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} - namespace: ${{ env.NAMESPACE }} - private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file + ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} \ No newline at end of file diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index 5cb9f372..d21c3a24 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -1,52 +1,27 @@ variables: - WORKFLOWNAME: - default: "Build and deploy an app to AKS with Helm" - description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" - resource: "ghBranch" - ACRRESOURCEGROUP: + RESOURCEGROUP: description: "the ACR resource group" - resource: "azResourceGroup" AZURECONTAINERREGISTRY: description: "the Azure container registry name" - resource: "azContainerRegistry" CONTAINERNAME: description: "the container image name" - resource: "containerName" - CLUSTERRESOURCEGROUP: - description: "the AKS cluster resource group" - resource: "azResourceGroup" CLUSTERNAME: description: "the AKS cluster name" - resource: "azClusterName" - DOCKERFILE: - description: "the path to the Dockerfile" - disablePrompt: true - resource: "dir" BUILDCONTEXTPATH: default: "." description: "the path to the Docker build context" - resource: "dir" CHARTPATH: default: "./charts" description: "the path to the Helm chart" disablePrompt: true - resource: "dir" CHARTOVERRIDEPATH: default: "./charts/production.yaml" description: "the path to the Helm chart override file" disablePrompt: true - resource: "dir" CHARTOVERRIDES: default: "replicas:2" description: "the Helm chart overrides" disablePrompt: true - NAMESPACE: - default: "default" - description: "the Kubernetes namespace" - PRIVATECLUSTER: - default: "false" - description: "set to true if the AKS cluster is private" - type: "bool" \ No newline at end of file diff --git a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml index 33bbbfd1..77fdb4f1 100644 --- a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml +++ b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml @@ -31,7 +31,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: {{WORKFLOWNAME}} +name: "Build and deploy an app to AKS" on: push: @@ -39,16 +39,12 @@ on: workflow_dispatch: env: - ACR_RESOURCE_GROUP: {{RESOURCEGROUP}} + RESOURCE_GROUP: {{RESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} - CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} KUSTOMIZE_PATH: {{KUSTOMIZEPATH}} - DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} - NAMESPACE: {{NAMESPACE}} - PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -71,7 +67,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -101,7 +97,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} + resource-group: ${{ env.RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -122,6 +118,4 @@ jobs: action: deploy manifests: ${{ steps.bake.outputs.manifestsBundle }} images: | - ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} - namespace: ${{ env.NAMESPACE }} - private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file + ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} \ No newline at end of file diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index e0f66c79..c15328a3 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -1,41 +1,18 @@ variables: - WORKFLOWNAME: - default: "Build and deploy an app to AKS with Helm" - description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" - resource: "ghBranch" - ACRRESOURCEGROUP: + RESOURCEGROUP: description: "the ACR resource group" - resource: "azResourceGroup" AZURECONTAINERREGISTRY: description: "the Azure container registry name" - resource: "azContainerRegistry" CONTAINERNAME: description: "the container image name" - resource: "containerName" - CLUSTERRESOURCEGROUP: - description: "the AKS cluster resource group" - resource: "azResourceGroup" CLUSTERNAME: description: "the AKS cluster name" - resource: "azClusterName" KUSTOMIZEPATH: default: "./overlays/production" description: "the path to the Kustomize directory" disablePrompt: true - resource: "dir" - DOCKERFILE: - description: "the path to the Dockerfile" - disablePrompt: true - resource: "dir" BUILDCONTEXTPATH: default: "." - description: "the path to the Docker build context" - NAMESPACE: - default: "default" - description: "the Kubernetes namespace" - PRIVATECLUSTER: - default: "false" - description: "set to true if the AKS cluster is private" - type: "bool" \ No newline at end of file + description: "the path to the Docker build context" \ No newline at end of file diff --git a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml index cded5a1d..971cb43c 100644 --- a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml +++ b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml @@ -27,7 +27,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: {{WORKFLOWNAME}} +name: "Build and deploy an app to AKS" on: push: @@ -35,16 +35,12 @@ on: workflow_dispatch: env: - ACR_RESOURCE_GROUP: {{ACRRESOURCEGROUP}} + RESOURCE_GROUP: {{RESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} - CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} DEPLOYMENT_MANIFEST_PATH: {{DEPLOYMENTMANIFESTPATH}} - DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} - NAMESPACE: {{NAMESPACE}} - PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -67,7 +63,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -97,7 +93,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} + resource-group: ${{ env.RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -110,6 +106,4 @@ jobs: manifests: ${{ env.DEPLOYMENT_MANIFEST_PATH }} images: | ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} - namespace: ${{ env.NAMESPACE }} - private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index a6df2448..d975fe25 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -1,41 +1,18 @@ variables: - WORKFLOWNAME: - default: "Build and deploy an app to AKS" - description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" - resource: "ghBranch" - ACRRESOURCEGROUP: + RESOURCEGROUP: description: "the ACR resource group" - resource: "azResourceGroup" AZURECONTAINERREGISTRY: description: "the Azure container registry name" - resource: "azContainerRegistry" CONTAINERNAME: description: "the container image name" - resource: "containerName" - CLUSTERRESOURCEGROUP: - description: "the AKS cluster resource group" - resource: "azResourceGroup" CLUSTERNAME: description: "the AKS cluster name" - resource: "azClusterName" DEPLOYMENTMANIFESTPATH: default: "./manifests" description: "the path to the Kubernetes deployment manifest" disablePrompt: true - resource: "dir" - DOCKERFILE: - description: "the path to the Dockerfile" - disablePrompt: true - resource: "dir" BUILDCONTEXTPATH: default: "." - description: "the path to the Docker build context" - NAMESPACE: - default: "default" - description: "the Kubernetes namespace" - PRIVATECLUSTER: - default: "false" - description: "set to true if the AKS cluster is private" - type: "bool" \ No newline at end of file + description: "the path to the Docker build context" \ No newline at end of file From f75510f89068b88056a4a18c6ec96b4b5aa0a57e Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Thu, 20 Jun 2024 12:13:12 -0400 Subject: [PATCH 11/44] rolled back dockerfile handling --- pkg/config/draftconfig.go | 2 +- pkg/prompts/prompts.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 648824e4..5351b66f 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -67,7 +67,7 @@ func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) erro for name, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling if val, ok := customConfig[name]; !ok || val == "" { - if variable.DefaultValue == "" && name != "DOCKERFILE" { + if variable.DefaultValue == "" { return errors.New("variable " + name + " has no default value") } log.Infof("Variable %s defaulting to value %s", name, variable.DefaultValue) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index fb56ddeb..50163862 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -40,7 +40,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st if variable.IsPromptDisabled { log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", name) noPromptDefaultValue := GetVariableDefaultValue(name, variable, inputs) - if noPromptDefaultValue == "" && name != "DOCKERFILE" { + if noPromptDefaultValue == "" { return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", name) } log.Debugf("Using default value %s for %s", noPromptDefaultValue, name) From f53059e02982fa1566863eefe9db0f6e041ed091 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Thu, 20 Jun 2024 12:21:10 -0400 Subject: [PATCH 12/44] rolled back resource type field --- pkg/config/draftconfig.go | 1 - template/workflows/helm/draft.yaml | 10 ---------- template/workflows/kustomize/draft.yaml | 8 -------- template/workflows/manifests/draft.yaml | 7 ------- 4 files changed, 26 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 5a724d66..648824e4 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -26,7 +26,6 @@ type BuilderVar struct { ExampleValues []string `yaml:"exampleValues"` IsPromptDisabled bool `yaml:"disablePrompt"` ReferenceVar string `yaml:"referenceVar"` - ResourceType string `yaml:"resource"` Type string `yaml:"type"` Value string `yaml:"value"` } diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index 5cb9f372..eab742ac 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -4,40 +4,30 @@ variables: description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" - resource: "ghBranch" ACRRESOURCEGROUP: description: "the ACR resource group" - resource: "azResourceGroup" AZURECONTAINERREGISTRY: description: "the Azure container registry name" - resource: "azContainerRegistry" CONTAINERNAME: description: "the container image name" - resource: "containerName" CLUSTERRESOURCEGROUP: description: "the AKS cluster resource group" - resource: "azResourceGroup" CLUSTERNAME: description: "the AKS cluster name" - resource: "azClusterName" DOCKERFILE: description: "the path to the Dockerfile" disablePrompt: true - resource: "dir" BUILDCONTEXTPATH: default: "." description: "the path to the Docker build context" - resource: "dir" CHARTPATH: default: "./charts" description: "the path to the Helm chart" disablePrompt: true - resource: "dir" CHARTOVERRIDEPATH: default: "./charts/production.yaml" description: "the path to the Helm chart override file" disablePrompt: true - resource: "dir" CHARTOVERRIDES: default: "replicas:2" description: "the Helm chart overrides" diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index e0f66c79..90ccb9b6 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -4,31 +4,23 @@ variables: description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" - resource: "ghBranch" ACRRESOURCEGROUP: description: "the ACR resource group" - resource: "azResourceGroup" AZURECONTAINERREGISTRY: description: "the Azure container registry name" - resource: "azContainerRegistry" CONTAINERNAME: description: "the container image name" - resource: "containerName" CLUSTERRESOURCEGROUP: description: "the AKS cluster resource group" - resource: "azResourceGroup" CLUSTERNAME: description: "the AKS cluster name" - resource: "azClusterName" KUSTOMIZEPATH: default: "./overlays/production" description: "the path to the Kustomize directory" disablePrompt: true - resource: "dir" DOCKERFILE: description: "the path to the Dockerfile" disablePrompt: true - resource: "dir" BUILDCONTEXTPATH: default: "." description: "the path to the Docker build context" diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index a6df2448..9a4659fc 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -4,31 +4,24 @@ variables: description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" - resource: "ghBranch" ACRRESOURCEGROUP: description: "the ACR resource group" - resource: "azResourceGroup" AZURECONTAINERREGISTRY: description: "the Azure container registry name" - resource: "azContainerRegistry" CONTAINERNAME: description: "the container image name" resource: "containerName" CLUSTERRESOURCEGROUP: description: "the AKS cluster resource group" - resource: "azResourceGroup" CLUSTERNAME: description: "the AKS cluster name" - resource: "azClusterName" DEPLOYMENTMANIFESTPATH: default: "./manifests" description: "the path to the Kubernetes deployment manifest" disablePrompt: true - resource: "dir" DOCKERFILE: description: "the path to the Dockerfile" disablePrompt: true - resource: "dir" BUILDCONTEXTPATH: default: "." description: "the path to the Docker build context" From f82c374fd545e3f688a84e989e332d6f659bd118 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 11:42:24 -0400 Subject: [PATCH 13/44] grouped default fields into a substruct --- cmd/create.go | 18 +-- cmd/create_test.go | 8 +- pkg/config/draftconfig.go | 24 ++-- pkg/prompts/prompts.go | 44 +------ pkg/prompts/prompts_test.go | 117 ++++++------------ .../addons/azure/webapp_routing/draft.yaml | 5 +- template/deployments/helm/draft.yaml | 24 ++-- template/deployments/kustomize/draft.yaml | 24 ++-- template/deployments/manifests/draft.yaml | 24 ++-- template/dockerfiles/clojure/draft.yaml | 6 +- template/dockerfiles/csharp/draft.yaml | 6 +- template/dockerfiles/erlang/draft.yaml | 9 +- template/dockerfiles/go/draft.yaml | 6 +- template/dockerfiles/gomodule/draft.yaml | 6 +- template/dockerfiles/gradle/draft.yaml | 9 +- template/dockerfiles/gradlew/draft.yaml | 9 +- template/dockerfiles/java/draft.yaml | 9 +- template/dockerfiles/javascript/draft.yaml | 6 +- template/dockerfiles/php/draft.yaml | 9 +- template/dockerfiles/python/draft.yaml | 9 +- template/dockerfiles/ruby/draft.yaml | 6 +- template/dockerfiles/rust/draft.yaml | 6 +- template/dockerfiles/swift/draft.yaml | 6 +- template/workflows/helm/draft.yaml | 18 +-- template/workflows/kustomize/draft.yaml | 8 +- template/workflows/manifests/draft.yaml | 8 +- 26 files changed, 209 insertions(+), 215 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index b1812c27..a62516a7 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -465,21 +465,21 @@ func validateConfigInputsToPrompts(required map[string]config.BuilderVar, provid // fill in missing vars using variable default references for name, variable := range required { - if customInputs[name] == "" && variable.ReferenceVar != "" { - if _, ok := customInputs[variable.ReferenceVar]; !ok { - log.Debugf("reference variable %s is empty, adding it in", variable.ReferenceVar) - customInputs[variable.ReferenceVar] = required[variable.ReferenceVar].DefaultValue + if customInputs[name] == "" && variable.Default.ReferenceVar != "" { + if _, ok := customInputs[variable.Default.ReferenceVar]; !ok { + log.Debugf("reference variable %s is empty, adding it in", variable.Default.ReferenceVar) + customInputs[variable.Default.ReferenceVar] = required[variable.Default.ReferenceVar].Default.Value } - log.Debugf("variable %s is empty, using default referenceVar value from %s", name, variable.ReferenceVar) - customInputs[name] = customInputs[variable.ReferenceVar] + log.Debugf("variable %s is empty, using default referenceVar value from %s", name, variable.Default.ReferenceVar) + customInputs[name] = customInputs[variable.Default.ReferenceVar] } } // fill in missing vars using variable default values for name, variable := range required { - if customInputs[name] == "" && variable.DefaultValue != "" { - log.Debugf("variable %s is empty, using default value %s", name, variable.DefaultValue) - customInputs[name] = variable.DefaultValue + if customInputs[name] == "" && variable.Default.Value != "" { + log.Debugf("variable %s is empty, using default value %s", name, variable.Default.Value) + customInputs[name] = variable.Default.Value } } diff --git a/cmd/create_test.go b/cmd/create_test.go index f8d70b90..3028a6ad 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -143,8 +143,12 @@ func TestInitConfig(t *testing.T) { func TestValidateConfigInputsToPromptsPass(t *testing.T) { required := map[string]config.BuilderVar{ - "REQUIRED_PROVIDED": {}, - "REQUIRED_DEFAULTED": {DefaultValue: "DEFAULT_VALUE"}, + "REQUIRED_PROVIDED": {}, + "REQUIRED_DEFAULTED": { + Default: config.BuilderVarDefault{ + Value: "DEFAULT_VALUE", + }, + }, } provided := []UserInputs{ {Name: "REQUIRED_PROVIDED", Value: "PROVIDED_VALUE"}, diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 5351b66f..8bd435ca 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -21,13 +21,17 @@ type FileNameOverride struct { } type BuilderVar struct { - DefaultValue string `yaml:"default"` - Description string `yaml:"description"` - ExampleValues []string `yaml:"exampleValues"` - IsPromptDisabled bool `yaml:"disablePrompt"` - ReferenceVar string `yaml:"referenceVar"` - Type string `yaml:"type"` - Value string `yaml:"value"` + Default BuilderVarDefault `yaml:"default"` + Description string `yaml:"description"` + ExampleValues []string `yaml:"exampleValues"` + Type string `yaml:"type"` + Value string `yaml:"value"` +} + +type BuilderVarDefault struct { + IsPromptDisabled bool `yaml:"disablePrompt"` + ReferenceVar string `yaml:"referenceVar"` + Value string `yaml:"value"` } func (d *DraftConfig) GetVariableExampleValues() map[string][]string { @@ -67,11 +71,11 @@ func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) erro for name, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling if val, ok := customConfig[name]; !ok || val == "" { - if variable.DefaultValue == "" { + if variable.Default.Value == "" { return errors.New("variable " + name + " has no default value") } - log.Infof("Variable %s defaulting to value %s", name, variable.DefaultValue) - customConfig[name] = variable.DefaultValue + log.Infof("Variable %s defaulting to value %s", name, variable.Default.Value) + customConfig[name] = variable.Default.Value } } diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 1aedbf2d..fdf77977 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -45,7 +45,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st continue } - if variable.IsPromptDisabled { + if variable.Default.IsPromptDisabled { log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", name) noPromptDefaultValue := GetVariableDefaultValue(name, variable, inputs) if noPromptDefaultValue == "" { @@ -80,8 +80,6 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal Variable.DefaultValue in that order. func GetVariableDefaultValue(variableName string, variable config.BuilderVar, inputs map[string]string) string { defaultValue := "" -<<<<<<< HEAD -======= if variableName == "APPNAME" { dirName, err := getCurrentDirNameFunc() @@ -93,35 +91,11 @@ func GetVariableDefaultValue(variableName string, variable config.BuilderVar, in return defaultValue } - for _, variableDefault := range variableDefaults { - if variableDefault.Name == variableName { - defaultValue = variableDefault.Value - log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) - if variableDefault.ReferenceVar != "" && inputs[variableDefault.ReferenceVar] != "" { - defaultValue = inputs[variableDefault.ReferenceVar] - log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variableDefault.ReferenceVar) - } - } - } - return defaultValue -} ->>>>>>> main - - if variableName == "APPNAME" { - dirName, err := getCurrentDirNameFunc() - if err != nil { - log.Errorf("Error retrieving current directory name: %s", err) - return defaultAppName - } - defaultValue = sanitizeAppName(dirName) - return defaultValue - } - - defaultValue = variable.DefaultValue + defaultValue = variable.Default.Value log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) - if variable.ReferenceVar != "" && inputs[variable.ReferenceVar] != "" { - defaultValue = inputs[variable.ReferenceVar] - log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variable.ReferenceVar) + if variable.Default.ReferenceVar != "" && inputs[variable.Default.ReferenceVar] != "" { + defaultValue = inputs[variable.Default.ReferenceVar] + log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variable.Default.ReferenceVar) } return defaultValue @@ -183,11 +157,7 @@ func appNameValidator(name string) error { } // RunDefaultableStringPrompt runs a prompt for a string variable, returning the user string input for the prompt -<<<<<<< HEAD func RunDefaultableStringPrompt(name, defaultValue string, customPrompt config.BuilderVar, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) { -======= -func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue string, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) { ->>>>>>> main if validate == nil { validate = NoBlankStringValidator } @@ -197,11 +167,7 @@ func RunDefaultableStringPrompt(customPrompt config.BuilderVar, defaultValue str if input == "" { return nil } -<<<<<<< HEAD if name == "APPNAME" { -======= - if customPrompt.Name == "APPNAME" { ->>>>>>> main if err := appNameValidator(input); err != nil { return err } diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index d71e9bb3..781a6d89 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -20,10 +20,14 @@ func TestGetVariableDefaultValue(t *testing.T) { variableName: "var1", variables: map[string]config.BuilderVar{ "var1": { - DefaultValue: "default-value-1", + Default: config.BuilderVarDefault{ + Value: "default-value-1", + }, }, "var2": { - DefaultValue: "default-value-2", + Default: config.BuilderVarDefault{ + Value: "default-value-2", + }, }, }, inputs: map[string]string{}, @@ -41,8 +45,10 @@ func TestGetVariableDefaultValue(t *testing.T) { variableName: "var1", variables: map[string]config.BuilderVar{ "var1": { - DefaultValue: "not-this-value", - ReferenceVar: "var2", + Default: config.BuilderVarDefault{ + ReferenceVar: "var2", + Value: "not-this-value", + }, }, }, inputs: map[string]string{ @@ -54,11 +60,15 @@ func TestGetVariableDefaultValue(t *testing.T) { variableName: "beforeVar", variables: map[string]config.BuilderVar{ "beforeVar": { - DefaultValue: "before-default-value", - ReferenceVar: "afterVar", + Default: config.BuilderVarDefault{ + ReferenceVar: "afterVar", + Value: "before-default-value", + }, }, "afterVar": { - DefaultValue: "not-this-value", + Default: config.BuilderVarDefault{ + Value: "not-this-value", + }, }, }, inputs: map[string]string{}, @@ -77,10 +87,7 @@ func TestGetVariableDefaultValue(t *testing.T) { func TestRunStringPrompt(t *testing.T) { tests := []struct { testName string -<<<<<<< HEAD variableName string -======= ->>>>>>> main prompt config.BuilderVar userInputs []string defaultValue string @@ -111,15 +118,9 @@ func TestRunStringPrompt(t *testing.T) { mockDirNameValue: "", }, { -<<<<<<< HEAD testName: "appNameUsesDirName", variableName: "APPNAME", prompt: config.BuilderVar{ -======= - testName: "appNameUsesDirName", - prompt: config.BuilderVar{ - Name: "APPNAME", ->>>>>>> main Description: "app name", }, userInputs: []string{"\n"}, @@ -129,15 +130,9 @@ func TestRunStringPrompt(t *testing.T) { mockDirNameValue: "currentdir", }, { -<<<<<<< HEAD testName: "invalidAppName", variableName: "APPNAME", prompt: config.BuilderVar{ -======= - testName: "invalidAppName", - prompt: config.BuilderVar{ - Name: "APPNAME", ->>>>>>> main Description: "app name", }, userInputs: []string{"--invalid-app-name\n"}, @@ -196,26 +191,15 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { { testName: "onlyNoPrompt", config: config.DraftConfig{ -<<<<<<< HEAD Variables: map[string]config.BuilderVar{ "var1": { - DefaultValue: "defaultValue", - Description: "var1 description", -======= - Variables: []config.BuilderVar{ - { - Name: "var1", + Default: config.BuilderVarDefault{ + IsPromptDisabled: true, + Value: "defaultValue", + }, Description: "var1 description", }, }, - VariableDefaults: []config.BuilderVarDefault{ - { - Name: "var1", - Value: "defaultValue", ->>>>>>> main - IsPromptDisabled: true, - }, - }, }, userInputs: []string{""}, want: map[string]string{ @@ -225,59 +209,34 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { }, { testName: "twoPromptTwoNoPrompt", config: config.DraftConfig{ -<<<<<<< HEAD Variables: map[string]config.BuilderVar{ "var1-no-prompt": { - DefaultValue: "defaultValueNoPrompt1", - Description: "var1 has IsPromptDisabled and should skip prompt and use default value", - IsPromptDisabled: true, + Default: config.BuilderVarDefault{ + IsPromptDisabled: true, + Value: "defaultValueNoPrompt1", + }, + Description: "var1 has IsPromptDisabled and should skip prompt and use default value", }, "var2-default": { - DefaultValue: "defaultValue2", - Description: "var2 has a default value and will receive an empty value, so it should use the default value", + Default: config.BuilderVarDefault{ + Value: "defaultValue2", + }, + Description: "var2 has a default value and will receive an empty value, so it should use the default value", }, "var3-no-prompt": { - DefaultValue: "defaultValueNoPrompt3", - Description: "var3 has IsPromptDisabled and should skip prompt and use default value", - IsPromptDisabled: true, + Default: config.BuilderVarDefault{ + IsPromptDisabled: true, + Value: "defaultValueNoPrompt3", + }, + Description: "var3 has IsPromptDisabled and should skip prompt and use default value", }, "var4": { - DefaultValue: "defaultValue4", - Description: "var4 has a default value, but has a value entered, so it should use the entered value", -======= - Variables: []config.BuilderVar{ - { - Name: "var1-no-prompt", - Description: "var1 has IsPromptDisabled and should skip prompt and use default value", - }, { - Name: "var2-default", - Description: "var2 has a default value and will receive an empty value, so it should use the default value", - }, { - Name: "var3-no-prompt", - Description: "var3 has IsPromptDisabled and should skip prompt and use default value", - }, { - Name: "var4", + Default: config.BuilderVarDefault{ + Value: "defaultValue4", + }, Description: "var4 has a default value, but has a value entered, so it should use the entered value", }, }, - VariableDefaults: []config.BuilderVarDefault{ - { - Name: "var1-no-prompt", - Value: "defaultValueNoPrompt1", - IsPromptDisabled: true, - }, { - Name: "var2-default", - Value: "defaultValue2", - }, { - Name: "var3-no-prompt", - Value: "defaultValueNoPrompt3", - IsPromptDisabled: true, - }, { - Name: "var4", - Value: "defaultValue4", ->>>>>>> main - }, - }, }, userInputs: []string{"\n", "entered-value-for-4\n"}, want: map[string]string{ diff --git a/template/addons/azure/webapp_routing/draft.yaml b/template/addons/azure/webapp_routing/draft.yaml index 9e1f04c2..74acaaaa 100644 --- a/template/addons/azure/webapp_routing/draft.yaml +++ b/template/addons/azure/webapp_routing/draft.yaml @@ -7,9 +7,10 @@ variables: ingress-host: description: "specify the host of the ingress resource" GENERATORLABEL: - default: "draft" + default: + disablePrompt: true + value: "draft" description: "the label to identify who generated the resource" - disablePrompt: true references: service: - name: "service-name" diff --git a/template/deployments/helm/draft.yaml b/template/deployments/helm/draft.yaml index 0c68354e..2d7c419b 100644 --- a/template/deployments/helm/draft.yaml +++ b/template/deployments/helm/draft.yaml @@ -1,23 +1,29 @@ variables: PORT: - default: 80 + default: + value: 80 description: "the port exposed in the application" APPNAME: description: "the name of the application" SERVICEPORT: + default: + referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" - referenceVar: "PORT" NAMESPACE: - default: default + default: + value: default description: " the namespace to place new resources in" IMAGENAME: + default: + referenceVar: "APPNAME" description: "the name of the image to use in the deployment" - referenceVar: "APPNAME" IMAGETAG: - default: "latest" + default: + disablePrompt: true + value: "latest" description: "the tag of the image to use in the deployment" - disablePrompt: true GENERATORLABEL: - default: "draft" - description: "the label to identify who generated the resource" - disablePrompt: true \ No newline at end of file + default: + disablePrompt: true + value: "draft" + description: "the label to identify who generated the resource" \ No newline at end of file diff --git a/template/deployments/kustomize/draft.yaml b/template/deployments/kustomize/draft.yaml index b22534b6..d8e4ab3c 100644 --- a/template/deployments/kustomize/draft.yaml +++ b/template/deployments/kustomize/draft.yaml @@ -1,23 +1,29 @@ variables: PORT: - default: 80 + default: + value: 80 description: "the port exposed in the application" APPNAME: description: "the name of the application" SERVICEPORT: + default: + referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" - referenceVar: "PORT" NAMESPACE: - default: default + default: + value: default description: " the namespace to place new resources in" IMAGENAME: + default: + referenceVar: "APPNAME" description: "the name of the image to use in the deployment" - referenceVar: "APPNAME" IMAGETAG: - default: "latest" + default: + disablePrompt: true + value: "latest" description: "the tag of the image to use in the deployment" - disablePrompt: true GENERATORLABEL: - default: "draft" - description: "the label to identify who generated the resource" - disablePrompt: true \ No newline at end of file + default: + disablePrompt: true + value: "draft" + description: "the label to identify who generated the resource" \ No newline at end of file diff --git a/template/deployments/manifests/draft.yaml b/template/deployments/manifests/draft.yaml index b22534b6..b61cabca 100644 --- a/template/deployments/manifests/draft.yaml +++ b/template/deployments/manifests/draft.yaml @@ -1,23 +1,29 @@ variables: PORT: - default: 80 + default: + value: 80 description: "the port exposed in the application" APPNAME: description: "the name of the application" SERVICEPORT: + default: + referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" - referenceVar: "PORT" NAMESPACE: - default: default + default: + value: default description: " the namespace to place new resources in" IMAGENAME: + default: + referenceVar: "APPNAME" description: "the name of the image to use in the deployment" - referenceVar: "APPNAME" IMAGETAG: - default: "latest" + default: + disablePrompt: true + value: "latest" description: "the tag of the image to use in the deployment" - disablePrompt: true GENERATORLABEL: - default: "draft" - description: "the label to identify who generated the resource" - disablePrompt: true \ No newline at end of file + default: + disablePrompt: true + value: "draft" + description: "the label to identify who generated the resource" \ No newline at end of file diff --git a/template/dockerfiles/clojure/draft.yaml b/template/dockerfiles/clojure/draft.yaml index 2ce6d5db..2c283672 100644 --- a/template/dockerfiles/clojure/draft.yaml +++ b/template/dockerfiles/clojure/draft.yaml @@ -2,10 +2,12 @@ language: clojure displayName: Clojure variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "8-jdk-alpine" + default: + value: "8-jdk-alpine" description: "the version of openjdk that the application uses" exampleValues: ["8-jdk-alpine","11-jdk-alpine","17-jdk-alpine","19-jdk-alpine"] \ No newline at end of file diff --git a/template/dockerfiles/csharp/draft.yaml b/template/dockerfiles/csharp/draft.yaml index 1672144e..ecaad3b6 100644 --- a/template/dockerfiles/csharp/draft.yaml +++ b/template/dockerfiles/csharp/draft.yaml @@ -2,11 +2,13 @@ language: csharp displayName: C# variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "5.0" + default: + value: "5.0" description: "the dotnet SDK version" type: float exampleValues: ["3.1","4.0","5.0","6.0"] \ No newline at end of file diff --git a/template/dockerfiles/erlang/draft.yaml b/template/dockerfiles/erlang/draft.yaml index 7b9b319a..37cabc4c 100644 --- a/template/dockerfiles/erlang/draft.yaml +++ b/template/dockerfiles/erlang/draft.yaml @@ -5,15 +5,18 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int BUILDERVERSION: - default: "24.2-alpine" + default: + value: "24.2-alpine" description: "the version of erlang used during the builder stage to generate the executable" exampleValues: ["24.2-alpine"] VERSION: - default: "3.15" + default: + value: "3.15" description: "the version of alpine used by the application" exampleValues: ["3.15"] \ No newline at end of file diff --git a/template/dockerfiles/go/draft.yaml b/template/dockerfiles/go/draft.yaml index d1be5724..4e16e7df 100644 --- a/template/dockerfiles/go/draft.yaml +++ b/template/dockerfiles/go/draft.yaml @@ -5,10 +5,12 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "1.18" + default: + value: "1.18" description: "the version of go used by the application" exampleValues: ["1.16", "1.17", "1.18", "1.19"] \ No newline at end of file diff --git a/template/dockerfiles/gomodule/draft.yaml b/template/dockerfiles/gomodule/draft.yaml index 3fb4c382..e9569424 100644 --- a/template/dockerfiles/gomodule/draft.yaml +++ b/template/dockerfiles/gomodule/draft.yaml @@ -5,10 +5,12 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "1.18" + default: + value: "1.18" description: "the version of go used by the application" exampleValues: ["1.16", "1.17", "1.18", "1.19"] \ No newline at end of file diff --git a/template/dockerfiles/gradle/draft.yaml b/template/dockerfiles/gradle/draft.yaml index 2f9c8e4e..fe77ebd4 100644 --- a/template/dockerfiles/gradle/draft.yaml +++ b/template/dockerfiles/gradle/draft.yaml @@ -5,14 +5,17 @@ nameOverrides: prefix: "." variables: BUILDERVERSION: - default: "jdk21" + default: + value: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "21-jre" + default: + value: "21-jre" description: "the java version used by the application" exampleValues: ["11-jre","17-jre","19-jre","21-jre"] \ No newline at end of file diff --git a/template/dockerfiles/gradlew/draft.yaml b/template/dockerfiles/gradlew/draft.yaml index 511be226..f76860cd 100644 --- a/template/dockerfiles/gradlew/draft.yaml +++ b/template/dockerfiles/gradlew/draft.yaml @@ -5,14 +5,17 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int BUILDERVERSION: - default: "jdk21" + default: + value: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] VERSION: - default: "21-jre" + default: + value: "21-jre" description: "the java version used by the application" exampleValues: ["11-jre","17-jre","19-jre","21-jre"] \ No newline at end of file diff --git a/template/dockerfiles/java/draft.yaml b/template/dockerfiles/java/draft.yaml index 5797546b..b7c8eb58 100644 --- a/template/dockerfiles/java/draft.yaml +++ b/template/dockerfiles/java/draft.yaml @@ -5,14 +5,17 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int BUILDERVERSION: - default: "3" + default: + value: "3" description: "the version of maven used during the builder stage to generate the executable" exampleValues: ["3-eclipse-temurin-11", "3-eclipse-temurin-17", "3-eclipse-temurin-21", "3 (jdk-21)"] VERSION: - default: "21-jre" + default: + value: "21-jre" description: "the java version used by the application" exampleValues: ["11-jre","17-jre","19-jre","21-jre"] \ No newline at end of file diff --git a/template/dockerfiles/javascript/draft.yaml b/template/dockerfiles/javascript/draft.yaml index dcce8adb..acada77a 100644 --- a/template/dockerfiles/javascript/draft.yaml +++ b/template/dockerfiles/javascript/draft.yaml @@ -5,10 +5,12 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "14" + default: + value: "14" description: "the version of node used in the application" exampleValues: ["10.16.3", "12.16.3", "14.15.4"] \ No newline at end of file diff --git a/template/dockerfiles/php/draft.yaml b/template/dockerfiles/php/draft.yaml index 4b3db86c..a0fe3a5f 100644 --- a/template/dockerfiles/php/draft.yaml +++ b/template/dockerfiles/php/draft.yaml @@ -5,14 +5,17 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int BUILDERVERSION: - default: "1" + default: + value: "1" description: "the version of composer installed during the build stage to be used by the application" exampleValues: ["1"] VERSION: - default: "7.1-apache" + default: + value: "7.1-apache" description: "the version of php used by the application" exampleValues: ["7.1-apache"] \ No newline at end of file diff --git a/template/dockerfiles/python/draft.yaml b/template/dockerfiles/python/draft.yaml index e9615b87..bd6de934 100644 --- a/template/dockerfiles/python/draft.yaml +++ b/template/dockerfiles/python/draft.yaml @@ -5,15 +5,18 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "3" + default: + value: "3" description: "the version of python used by the application" exampleValues: ["3.9", "3.8", "3.7", "3.6"] ENTRYPOINT: - default: "app.py" + default: + value: "app.py" description: "the entrypoint file of the repository" type: string exampleValues: ["app.py", "main.py"] \ No newline at end of file diff --git a/template/dockerfiles/ruby/draft.yaml b/template/dockerfiles/ruby/draft.yaml index ed165f2f..76fc4a57 100644 --- a/template/dockerfiles/ruby/draft.yaml +++ b/template/dockerfiles/ruby/draft.yaml @@ -5,10 +5,12 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "3.1.2" + default: + value: "3.1.2" description: "the version of ruby used by the application" exampleValues: ["3.1.2", "2.6", "2.5", "2.4"] \ No newline at end of file diff --git a/template/dockerfiles/rust/draft.yaml b/template/dockerfiles/rust/draft.yaml index e76dff7a..05c270fb 100644 --- a/template/dockerfiles/rust/draft.yaml +++ b/template/dockerfiles/rust/draft.yaml @@ -5,10 +5,12 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "1.70.0" + default: + value: "1.70.0" description: "the version of rust used by the application" exampleValues: ["1.70.0","1.65.0", "1.60", "1.54", "1.53"] \ No newline at end of file diff --git a/template/dockerfiles/swift/draft.yaml b/template/dockerfiles/swift/draft.yaml index 1a984afb..44151e68 100644 --- a/template/dockerfiles/swift/draft.yaml +++ b/template/dockerfiles/swift/draft.yaml @@ -5,10 +5,12 @@ nameOverrides: prefix: "." variables: PORT: - default: "80" + default: + value: "80" description: "the port exposed in the application" type: int VERSION: - default: "5.5" + default: + value: "5.5" description: "the version of swift used by the application" exampleValues: ["5.2","5.5"] \ No newline at end of file diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index d21c3a24..48e0abbf 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -10,18 +10,22 @@ variables: CLUSTERNAME: description: "the AKS cluster name" BUILDCONTEXTPATH: - default: "." + default: + value: "." description: "the path to the Docker build context" CHARTPATH: - default: "./charts" + default: + disablePrompt: true + value: "./charts" description: "the path to the Helm chart" - disablePrompt: true CHARTOVERRIDEPATH: - default: "./charts/production.yaml" + default: + disablePrompt: true + value: "./charts/production.yaml" description: "the path to the Helm chart override file" - disablePrompt: true CHARTOVERRIDES: - default: "replicas:2" + default: + disablePrompt: true + value: "replicas:2" description: "the Helm chart overrides" - disablePrompt: true \ No newline at end of file diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index c15328a3..000d6d4a 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -10,9 +10,11 @@ variables: CLUSTERNAME: description: "the AKS cluster name" KUSTOMIZEPATH: - default: "./overlays/production" + default: + disablePrompt: true + value: "./overlays/production" description: "the path to the Kustomize directory" - disablePrompt: true BUILDCONTEXTPATH: - default: "." + default: + value: "." description: "the path to the Docker build context" \ No newline at end of file diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index d975fe25..b5bdd51d 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -10,9 +10,11 @@ variables: CLUSTERNAME: description: "the AKS cluster name" DEPLOYMENTMANIFESTPATH: - default: "./manifests" + default: + disablePrompt: true + value: "./manifests" description: "the path to the Kubernetes deployment manifest" - disablePrompt: true BUILDCONTEXTPATH: - default: "." + default: + value: "." description: "the path to the Docker build context" \ No newline at end of file From 76f92af0c3116d86e2351d6f8c63c55e3239ae9e Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 13:06:01 -0400 Subject: [PATCH 14/44] typo --- .../helm/.github/workflows/azure-kubernetes-service-helm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml index d9291551..0324d454 100644 --- a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml +++ b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml @@ -32,7 +32,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: ""Build and deploy an app to AKS with Helm" +name: "Build and deploy an app to AKS with Helm" on: push: From 568f93b0ead2d04cd93de1da91cd13afc3bb2d36 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 13:09:31 -0400 Subject: [PATCH 15/44] typo --- .../helm/.github/workflows/azure-kubernetes-service-helm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml index d9291551..0324d454 100644 --- a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml +++ b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml @@ -32,7 +32,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: ""Build and deploy an app to AKS with Helm" +name: "Build and deploy an app to AKS with Helm" on: push: From e2c5a9138f098b24800892b0eb17b6570ab978ec Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 13:24:08 -0400 Subject: [PATCH 16/44] integrated DevHub's functionalities --- .../workflows/azure-kubernetes-service-helm.yml | 16 +++++++++++----- template/workflows/helm/draft.yaml | 13 +++++++++++++ .../azure-kubernetes-service-kustomize.yml | 16 +++++++++++----- template/workflows/kustomize/draft.yaml | 15 ++++++++++++++- .../workflows/azure-kubernetes-service.yml | 14 ++++++++++---- template/workflows/manifests/draft.yaml | 15 ++++++++++++++- 6 files changed, 73 insertions(+), 16 deletions(-) diff --git a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml index 0324d454..3980da64 100644 --- a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml +++ b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml @@ -32,7 +32,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: "Build and deploy an app to AKS with Helm" +name: {{WORKFLOWNAME}} on: push: @@ -40,14 +40,18 @@ on: workflow_dispatch: env: - RESOURCE_GROUP: {{RESOURCEGROUP}} + ACR_RESOURCE_GROUP: {{ACRRESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} + CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} + DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} CHART_PATH: {{CHARTPATH}} CHART_OVERRIDE_PATH: {{CHARTOVERRIDEPATH}} CHART_OVERRIDES: {{CHARTOVERRIDES}} + NAMESPACE: {{NAMESPACE}} + PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -70,7 +74,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} -f ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -100,7 +104,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.RESOURCE_GROUP }} + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -123,4 +127,6 @@ jobs: action: deploy manifests: ${{ steps.bake.outputs.manifestsBundle }} images: | - ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} \ No newline at end of file + ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + namespace: ${{ env.NAMESPACE }} + private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index 5d61f815..fb3770f5 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -1,4 +1,8 @@ variables: + WORKFLOWNAME: + default: + value: "Build and deploy an app to AKS with Helm" + description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" ACRRESOURCEGROUP: @@ -35,4 +39,13 @@ variables: disablePrompt: true value: "replicas:2" description: "the Helm chart overrides" + NAMESPACE: + default: + value: "default" + description: "the Kubernetes namespace" + PRIVATECLUSTER: + default: + value: "false" + description: "set to true if the AKS cluster is private" + type: "bool" \ No newline at end of file diff --git a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml index 77fdb4f1..3dbdde61 100644 --- a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml +++ b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml @@ -31,7 +31,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: "Build and deploy an app to AKS" +name: {{WORKFLOWNAME}} on: push: @@ -39,12 +39,16 @@ on: workflow_dispatch: env: - RESOURCE_GROUP: {{RESOURCEGROUP}} + ACR_RESOURCE_GROUP: {{ACRRESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} + CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} KUSTOMIZE_PATH: {{KUSTOMIZEPATH}} + DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} + NAMESPACE: {{NAMESPACE}} + PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -67,7 +71,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} -f ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -97,7 +101,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.RESOURCE_GROUP }} + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -118,4 +122,6 @@ jobs: action: deploy manifests: ${{ steps.bake.outputs.manifestsBundle }} images: | - ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} \ No newline at end of file + ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + namespace: ${{ env.NAMESPACE }} + private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index fb20a59d..d2f109ff 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -1,4 +1,8 @@ variables: + WORKFLOWNAME: + default: + value: "Build and deploy an app to AKS" + description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" ACRRESOURCEGROUP: @@ -24,4 +28,13 @@ variables: BUILDCONTEXTPATH: default: value: "." - description: "the path to the Docker build context" \ No newline at end of file + description: "the path to the Docker build context" + NAMESPACE: + default: + value: "default" + description: "the Kubernetes namespace" + PRIVATECLUSTER: + default: + value: "false" + description: "set to true if the AKS cluster is private" + type: "bool"s \ No newline at end of file diff --git a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml index 971cb43c..9dc76c86 100644 --- a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml +++ b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml @@ -27,7 +27,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: "Build and deploy an app to AKS" +name: {{WORKFLOWNAME}} on: push: @@ -35,12 +35,16 @@ on: workflow_dispatch: env: - RESOURCE_GROUP: {{RESOURCEGROUP}} + ACR_RESOURCE_GROUP: {{ACRRESOURCEGROUP}} AZURE_CONTAINER_REGISTRY: {{AZURECONTAINERREGISTRY}} CONTAINER_NAME: {{CONTAINERNAME}} + CLUSTER_RESOURCE_GROUP: {{CLUSTERRESOURCEGROUP}} CLUSTER_NAME: {{CLUSTERNAME}} DEPLOYMENT_MANIFEST_PATH: {{DEPLOYMENTMANIFESTPATH}} + DOCKER_FILE: {{DOCKERFILE}} BUILD_CONTEXT_PATH: {{BUILDCONTEXTPATH}} + NAMESPACE: {{NAMESPACE}} + PRIVATE_CLUSTER: {{PRIVATECLUSTER}} jobs: buildImage: @@ -63,7 +67,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} -f ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} deploy: permissions: actions: read @@ -93,7 +97,7 @@ jobs: - name: Get K8s context uses: azure/aks-set-context@v3 with: - resource-group: ${{ env.RESOURCE_GROUP }} + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} cluster-name: ${{ env.CLUSTER_NAME }} admin: 'false' use-kubelogin: 'true' @@ -106,4 +110,6 @@ jobs: manifests: ${{ env.DEPLOYMENT_MANIFEST_PATH }} images: | ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + namespace: ${{ env.NAMESPACE }} + private-cluster: ${{ env.PRIVATE_CLUSTER }} \ No newline at end of file diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index f3ac670e..b34b8dff 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -1,4 +1,8 @@ variables: + WORKFLOWNAME: + default: + value: "Build and deploy an app to AKS" + description: "the name of the workflow" BRANCHNAME: description: "the Github branch to automatically deploy from" ACRRESOURCEGROUP: @@ -25,4 +29,13 @@ variables: BUILDCONTEXTPATH: default: value: "." - description: "the path to the Docker build context" \ No newline at end of file + description: "the path to the Docker build context" + NAMESPACE: + default: + value: "default" + description: "the Kubernetes namespace" + PRIVATECLUSTER: + default: + value: "false" + description: "set to true if the AKS cluster is private" + type: "bool" \ No newline at end of file From 33d770ec611a0d2ada4426a6effb7c846828a87a Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 15:01:28 -0400 Subject: [PATCH 17/44] changed data structure for BuilderVars from map back to a slice --- cmd/create.go | 52 +++++++++++-------- cmd/create_test.go | 19 ++++--- pkg/config/draftconfig.go | 27 +++++----- pkg/osutil/osutil.go | 8 +-- pkg/osutil/osutil_test.go | 2 +- pkg/prompts/prompts.go | 26 +++++----- pkg/prompts/prompts_test.go | 19 ++++--- .../addons/azure/webapp_routing/draft.yaml | 8 +-- template/deployments/helm/draft.yaml | 14 ++--- template/deployments/kustomize/draft.yaml | 14 ++--- template/deployments/manifests/draft.yaml | 14 ++--- template/dockerfiles/clojure/draft.yaml | 4 +- template/dockerfiles/csharp/draft.yaml | 4 +- template/dockerfiles/erlang/draft.yaml | 6 +-- template/dockerfiles/go/draft.yaml | 4 +- template/dockerfiles/gomodule/draft.yaml | 4 +- template/dockerfiles/gradle/draft.yaml | 6 +-- template/dockerfiles/gradlew/draft.yaml | 6 +-- template/dockerfiles/java/draft.yaml | 6 +-- template/dockerfiles/javascript/draft.yaml | 4 +- template/dockerfiles/php/draft.yaml | 6 +-- template/dockerfiles/python/draft.yaml | 6 +-- template/dockerfiles/ruby/draft.yaml | 4 +- template/dockerfiles/rust/draft.yaml | 4 +- template/dockerfiles/swift/draft.yaml | 4 +- template/workflows/helm/draft.yaml | 18 +++---- template/workflows/kustomize/draft.yaml | 14 ++--- template/workflows/manifests/draft.yaml | 14 ++--- 28 files changed, 169 insertions(+), 148 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index a62516a7..862f6cf5 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -265,15 +265,24 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan return err } - // Check for existing duplicate defaults + // Check for existing duplicate defualts for k, v := range extractedValues { - if builderVar, ok := langConfig.Variables[k]; ok { - builderVar.Value = v - } else { - langConfig.Variables[k] = config.BuilderVar{ - Value: v, + variableExists := false + for i, variable := range langConfig.Variables { + if k == variable.Name { + variableExists = true + langConfig.Variables[i].Default.Value = v + break } } + if !variableExists { + langConfig.Variables = append(langConfig.Variables, config.BuilderVar{ + Name: k, + Default: config.BuilderVarDefault{ + Value: v, + }, + }) + } } var inputs map[string]string @@ -455,7 +464,7 @@ func init() { rootCmd.AddCommand(newCreateCmd()) } -func validateConfigInputsToPrompts(required map[string]config.BuilderVar, provided []UserInputs) (map[string]string, error) { +func validateConfigInputsToPrompts(required []config.BuilderVar, provided []UserInputs) (map[string]string, error) { customInputs := make(map[string]string) // set inputs to provided values @@ -464,28 +473,27 @@ func validateConfigInputsToPrompts(required map[string]config.BuilderVar, provid } // fill in missing vars using variable default references - for name, variable := range required { - if customInputs[name] == "" && variable.Default.ReferenceVar != "" { - if _, ok := customInputs[variable.Default.ReferenceVar]; !ok { - log.Debugf("reference variable %s is empty, adding it in", variable.Default.ReferenceVar) - customInputs[variable.Default.ReferenceVar] = required[variable.Default.ReferenceVar].Default.Value - } - log.Debugf("variable %s is empty, using default referenceVar value from %s", name, variable.Default.ReferenceVar) - customInputs[name] = customInputs[variable.Default.ReferenceVar] + for _, variable := range required { + if customInputs[variable.Name] == "" && variable.Default.ReferenceVar != "" { + log.Debugf("variable %s is empty, using default referenceVar value from %s", variable.Name, variable.Default.ReferenceVar) + customInputs[variable.Name] = customInputs[variable.Default.ReferenceVar] } } // fill in missing vars using variable default values - for name, variable := range required { - if customInputs[name] == "" && variable.Default.Value != "" { - log.Debugf("variable %s is empty, using default value %s", name, variable.Default.Value) - customInputs[name] = variable.Default.Value + for _, variable := range required { + if customInputs[variable.Name] == "" && variable.Default.Value != "" { + log.Debugf("variable %s is empty, using default value %s", variable.Name, variable.Default.Value) + customInputs[variable.Name] = variable.Default.Value } } - for name, variable := range required { - if _, ok := customInputs[name]; !ok { - return nil, fmt.Errorf("config missing required variable: %s with description: %s", name, variable.Description) + for _, variable := range required { + value, ok := customInputs[variable.Name] + if !ok { + return nil, fmt.Errorf("config missing required variable: %s with description: %s", variable.Name, variable.Description) + } else if value == "" { + return nil, fmt.Errorf("value for variable %s is empty", variable.Name) } } diff --git a/cmd/create_test.go b/cmd/create_test.go index 3028a6ad..bfcff610 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -142,9 +142,12 @@ func TestInitConfig(t *testing.T) { } func TestValidateConfigInputsToPromptsPass(t *testing.T) { - required := map[string]config.BuilderVar{ - "REQUIRED_PROVIDED": {}, - "REQUIRED_DEFAULTED": { + required := []config.BuilderVar{ + { + Name: "REQUIRED_PROVIDED", + }, + { + Name: "REQUIRED_DEFAULTED", Default: config.BuilderVarDefault{ Value: "DEFAULT_VALUE", }, @@ -160,9 +163,13 @@ func TestValidateConfigInputsToPromptsPass(t *testing.T) { } func TestValidateConfigInputsToPromptsMissing(t *testing.T) { - required := map[string]config.BuilderVar{ - "REQUIRED_PROVIDED": {}, - "REQUIRED_MISSING": {}, + required := []config.BuilderVar{ + { + Name: "REQUIRED_PROVIDED", + }, + { + Name: "REQUIRED_MISSING", + }, } provided := []UserInputs{ {Name: "REQUIRED_PROVIDED"}, diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 8bd435ca..930f9def 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -8,9 +8,9 @@ import ( // TODO: remove Name Overrides since we don't need them anymore type DraftConfig struct { - DisplayName string `yaml:"displayName"` - NameOverrides []FileNameOverride `yaml:"nameOverrides"` - Variables map[string]BuilderVar `yaml:"variables"` + DisplayName string `yaml:"displayName"` + NameOverrides []FileNameOverride `yaml:"nameOverrides"` + Variables []BuilderVar `yaml:"variables"` nameOverrideMap map[string]string } @@ -21,6 +21,7 @@ type FileNameOverride struct { } type BuilderVar struct { + Name string `yaml:"name"` Default BuilderVarDefault `yaml:"default"` Description string `yaml:"description"` ExampleValues []string `yaml:"exampleValues"` @@ -36,9 +37,9 @@ type BuilderVarDefault struct { func (d *DraftConfig) GetVariableExampleValues() map[string][]string { variableExampleValues := make(map[string][]string) - for name, variable := range d.Variables { + for _, variable := range d.Variables { if len(variable.ExampleValues) > 0 { - variableExampleValues[name] = variable.ExampleValues + variableExampleValues[variable.Name] = variable.ExampleValues } } @@ -68,14 +69,14 @@ func (d *DraftConfig) GetNameOverride(path string) string { // ApplyDefaultVariables will apply the defaults to variables that are not already set func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) error { - for name, variable := range d.Variables { + for _, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling - if val, ok := customConfig[name]; !ok || val == "" { + if val, ok := customConfig[variable.Name]; !ok || val == "" { if variable.Default.Value == "" { - return errors.New("variable " + name + " has no default value") + return errors.New("variable " + variable.Name + " has no default value") } - log.Infof("Variable %s defaulting to value %s", name, variable.Default.Value) - customConfig[name] = variable.Default.Value + log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Default.Value) + customConfig[variable.Name] = variable.Default.Value } } @@ -89,11 +90,11 @@ type TemplateVariableRecorder interface { func (d *DraftConfig) VariableMap() (map[string]string, error) { varMap := make(map[string]string) - for name, variable := range d.Variables { + for _, variable := range d.Variables { if variable.Value == "" { - return nil, errors.New("variable " + name + " has no default value") + return nil, errors.New("variable " + variable.Name + " has no default value") } - varMap[name] = variable.Value + varMap[variable.Name] = variable.Value } return varMap, nil diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index 7e7ea8d4..eab99aea 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -107,12 +107,12 @@ func CopyDir( return err } } else { - fileContent, err := ReplaceTemplateVariables(fileSys, srcPath, customInputs) + fileContent, err := replaceTemplateVariables(fileSys, srcPath, customInputs) if err != nil { return err } - if err = CheckAllVariablesSubstituted(string(fileContent)); err != nil { + if err = checkAllVariablesSubstituted(string(fileContent)); err != nil { return fmt.Errorf("error substituting file %s: %w", srcPath, err) } @@ -131,7 +131,7 @@ If any draft variables are found, an error is returned. Draft variables are defined as a string of non-whitespace characters starting with a non-period character wrapped in double curly braces. The non-period first character constraint is used to avoid matching helm template functions. */ -func CheckAllVariablesSubstituted(fileContent string) error { +func checkAllVariablesSubstituted(fileContent string) error { if unsubstitutedVars := draftVariableRegex.FindAllString(fileContent, -1); len(unsubstitutedVars) > 0 { unsubstitutedVarsString := strings.Join(unsubstitutedVars, ", ") return fmt.Errorf("unsubstituted variable: %s", unsubstitutedVarsString) @@ -139,7 +139,7 @@ func CheckAllVariablesSubstituted(fileContent string) error { return nil } -func ReplaceTemplateVariables(fileSys fs.FS, srcPath string, customInputs map[string]string) ([]byte, error) { +func replaceTemplateVariables(fileSys fs.FS, srcPath string, customInputs map[string]string) ([]byte, error) { file, err := fs.ReadFile(fileSys, srcPath) if err != nil { return nil, err diff --git a/pkg/osutil/osutil_test.go b/pkg/osutil/osutil_test.go index 8536a77a..ed108062 100644 --- a/pkg/osutil/osutil_test.go +++ b/pkg/osutil/osutil_test.go @@ -110,7 +110,7 @@ func TestAllVariablesSubstituted(t *testing.T) { for _, test := range tests { t.Run(test.String, func(t *testing.T) { - err := CheckAllVariablesSubstituted(test.String) + err := checkAllVariablesSubstituted(test.String) didError := err != nil assert.Equal(t, test.ExpectError, didError) }) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index fdf77977..8d401f86 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -39,38 +39,38 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st inputs := make(map[string]string) - for name, variable := range config.Variables { - if val, ok := skipMap[name]; ok && val != "" { - log.Debugf("Skipping prompt for %s", name) + for _, variable := range config.Variables { + if val, ok := skipMap[variable.Name]; ok && val != "" { + log.Debugf("Skipping prompt for %s", variable.Name) continue } if variable.Default.IsPromptDisabled { - log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", name) - noPromptDefaultValue := GetVariableDefaultValue(name, variable, inputs) + log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", variable.Name) + noPromptDefaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) if noPromptDefaultValue == "" { - return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", name) + return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", variable.Name) } - log.Debugf("Using default value %s for %s", noPromptDefaultValue, name) - inputs[name] = noPromptDefaultValue + log.Debugf("Using default value %s for %s", noPromptDefaultValue, variable.Name) + inputs[variable.Name] = noPromptDefaultValue continue } - log.Debugf("constructing prompt for: %s", name) + log.Debugf("constructing prompt for: %s", variable.Name) if variable.Type == "bool" { input, err := RunBoolPrompt(variable, Stdin, Stdout) if err != nil { return nil, err } - inputs[name] = input + inputs[variable.Name] = input } else { - defaultValue := GetVariableDefaultValue(name, variable, inputs) + defaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) - stringInput, err := RunDefaultableStringPrompt(name, defaultValue, variable, nil, Stdin, Stdout) + stringInput, err := RunDefaultableStringPrompt(variable.Name, defaultValue, variable, nil, Stdin, Stdout) if err != nil { return nil, err } - inputs[name] = stringInput + inputs[variable.Name] = stringInput } } diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index 781a6d89..323cc8a8 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -191,8 +191,9 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { { testName: "onlyNoPrompt", config: config.DraftConfig{ - Variables: map[string]config.BuilderVar{ - "var1": { + Variables: []config.BuilderVar{ + { + Name: "var1", Default: config.BuilderVarDefault{ IsPromptDisabled: true, Value: "defaultValue", @@ -209,28 +210,32 @@ func TestRunPromptsFromConfigWithSkipsIO(t *testing.T) { }, { testName: "twoPromptTwoNoPrompt", config: config.DraftConfig{ - Variables: map[string]config.BuilderVar{ - "var1-no-prompt": { + Variables: []config.BuilderVar{ + { + Name: "var1-no-prompt", Default: config.BuilderVarDefault{ IsPromptDisabled: true, Value: "defaultValueNoPrompt1", }, Description: "var1 has IsPromptDisabled and should skip prompt and use default value", }, - "var2-default": { + { + Name: "var2-default", Default: config.BuilderVarDefault{ Value: "defaultValue2", }, Description: "var2 has a default value and will receive an empty value, so it should use the default value", }, - "var3-no-prompt": { + { + Name: "var3-no-prompt", Default: config.BuilderVarDefault{ IsPromptDisabled: true, Value: "defaultValueNoPrompt3", }, Description: "var3 has IsPromptDisabled and should skip prompt and use default value", }, - "var4": { + { + Name: "var4", Default: config.BuilderVarDefault{ Value: "defaultValue4", }, diff --git a/template/addons/azure/webapp_routing/draft.yaml b/template/addons/azure/webapp_routing/draft.yaml index 74acaaaa..0e5e9dc2 100644 --- a/template/addons/azure/webapp_routing/draft.yaml +++ b/template/addons/azure/webapp_routing/draft.yaml @@ -1,12 +1,12 @@ variables: - ingress-tls-cert-keyvault-uri: + - name: "ingress-tls-cert-keyvault-uri" description: "the keyvault uri for the tls certificate" - ingress-use-osm-mtls: + - name: "ingress-use-osm-mtls" description: "use open service mesh mutual-tls" type: "bool" - ingress-host: + - name: "ingress-host" description: "specify the host of the ingress resource" - GENERATORLABEL: + - name: "GENERATORLABEL" default: disablePrompt: true value: "draft" diff --git a/template/deployments/helm/draft.yaml b/template/deployments/helm/draft.yaml index 2d7c419b..7faf524d 100644 --- a/template/deployments/helm/draft.yaml +++ b/template/deployments/helm/draft.yaml @@ -1,28 +1,28 @@ variables: - PORT: + - name: "PORT" default: value: 80 description: "the port exposed in the application" - APPNAME: + - name: "APPNAME" description: "the name of the application" - SERVICEPORT: + - name: "SERVICEPORT" default: referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" - NAMESPACE: + - name: "NAMESPACE" default: value: default description: " the namespace to place new resources in" - IMAGENAME: + - name: "IMAGENAME" default: referenceVar: "APPNAME" description: "the name of the image to use in the deployment" - IMAGETAG: + - name: "IMAGETAG" default: disablePrompt: true value: "latest" description: "the tag of the image to use in the deployment" - GENERATORLABEL: + - name: "GENERATORLABEL" default: disablePrompt: true value: "draft" diff --git a/template/deployments/kustomize/draft.yaml b/template/deployments/kustomize/draft.yaml index d8e4ab3c..6b27b237 100644 --- a/template/deployments/kustomize/draft.yaml +++ b/template/deployments/kustomize/draft.yaml @@ -1,28 +1,28 @@ variables: - PORT: + - name: "PORT" default: value: 80 description: "the port exposed in the application" - APPNAME: + - name: "APPNAME" description: "the name of the application" - SERVICEPORT: + - name: "SERVICEPORT" default: referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" - NAMESPACE: + - name: "NAMESPACE" default: value: default description: " the namespace to place new resources in" - IMAGENAME: + - name: "IMAGENAME" default: referenceVar: "APPNAME" description: "the name of the image to use in the deployment" - IMAGETAG: + - name: "IMAGETAG" default: disablePrompt: true value: "latest" description: "the tag of the image to use in the deployment" - GENERATORLABEL: + - name: "GENERATORLABEL" default: disablePrompt: true value: "draft" diff --git a/template/deployments/manifests/draft.yaml b/template/deployments/manifests/draft.yaml index b61cabca..d1843f41 100644 --- a/template/deployments/manifests/draft.yaml +++ b/template/deployments/manifests/draft.yaml @@ -1,28 +1,28 @@ variables: - PORT: + - name: "PORT" default: value: 80 description: "the port exposed in the application" - APPNAME: + - name: "APPNAME" description: "the name of the application" - SERVICEPORT: + - name: "SERVICEPORT" default: referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" - NAMESPACE: + - name: "NAMESPACE" default: value: default description: " the namespace to place new resources in" - IMAGENAME: + - name: "IMAGENAME" default: referenceVar: "APPNAME" description: "the name of the image to use in the deployment" - IMAGETAG: + - name: "IMAGETAG" default: disablePrompt: true value: "latest" description: "the tag of the image to use in the deployment" - GENERATORLABEL: + - name: "GENERATORLABEL" default: disablePrompt: true value: "draft" diff --git a/template/dockerfiles/clojure/draft.yaml b/template/dockerfiles/clojure/draft.yaml index 2c283672..68972ec8 100644 --- a/template/dockerfiles/clojure/draft.yaml +++ b/template/dockerfiles/clojure/draft.yaml @@ -1,12 +1,12 @@ language: clojure displayName: Clojure variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "8-jdk-alpine" description: "the version of openjdk that the application uses" diff --git a/template/dockerfiles/csharp/draft.yaml b/template/dockerfiles/csharp/draft.yaml index ecaad3b6..4b2e667e 100644 --- a/template/dockerfiles/csharp/draft.yaml +++ b/template/dockerfiles/csharp/draft.yaml @@ -1,12 +1,12 @@ language: csharp displayName: C# variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "5.0" description: "the dotnet SDK version" diff --git a/template/dockerfiles/erlang/draft.yaml b/template/dockerfiles/erlang/draft.yaml index 37cabc4c..4263f4d2 100644 --- a/template/dockerfiles/erlang/draft.yaml +++ b/template/dockerfiles/erlang/draft.yaml @@ -4,17 +4,17 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - BUILDERVERSION: + - name: "BUILDERVERSION" default: value: "24.2-alpine" description: "the version of erlang used during the builder stage to generate the executable" exampleValues: ["24.2-alpine"] - VERSION: + - name: "VERSION" default: value: "3.15" description: "the version of alpine used by the application" diff --git a/template/dockerfiles/go/draft.yaml b/template/dockerfiles/go/draft.yaml index 4e16e7df..525320ba 100644 --- a/template/dockerfiles/go/draft.yaml +++ b/template/dockerfiles/go/draft.yaml @@ -4,12 +4,12 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "1.18" description: "the version of go used by the application" diff --git a/template/dockerfiles/gomodule/draft.yaml b/template/dockerfiles/gomodule/draft.yaml index e9569424..5c8d129c 100644 --- a/template/dockerfiles/gomodule/draft.yaml +++ b/template/dockerfiles/gomodule/draft.yaml @@ -4,12 +4,12 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "1.18" description: "the version of go used by the application" diff --git a/template/dockerfiles/gradle/draft.yaml b/template/dockerfiles/gradle/draft.yaml index fe77ebd4..100aeef6 100644 --- a/template/dockerfiles/gradle/draft.yaml +++ b/template/dockerfiles/gradle/draft.yaml @@ -4,17 +4,17 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - BUILDERVERSION: + - name: "BUILDERVERSION" default: value: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "21-jre" description: "the java version used by the application" diff --git a/template/dockerfiles/gradlew/draft.yaml b/template/dockerfiles/gradlew/draft.yaml index f76860cd..c031c8dd 100644 --- a/template/dockerfiles/gradlew/draft.yaml +++ b/template/dockerfiles/gradlew/draft.yaml @@ -4,17 +4,17 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - BUILDERVERSION: + - name: "BUILDERVERSION" default: value: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] - VERSION: + - name: "VERSION" default: value: "21-jre" description: "the java version used by the application" diff --git a/template/dockerfiles/java/draft.yaml b/template/dockerfiles/java/draft.yaml index b7c8eb58..e5512851 100644 --- a/template/dockerfiles/java/draft.yaml +++ b/template/dockerfiles/java/draft.yaml @@ -4,17 +4,17 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - BUILDERVERSION: + - name: "BUILDERVERSION" default: value: "3" description: "the version of maven used during the builder stage to generate the executable" exampleValues: ["3-eclipse-temurin-11", "3-eclipse-temurin-17", "3-eclipse-temurin-21", "3 (jdk-21)"] - VERSION: + - name: "VERSION" default: value: "21-jre" description: "the java version used by the application" diff --git a/template/dockerfiles/javascript/draft.yaml b/template/dockerfiles/javascript/draft.yaml index acada77a..4daa6cc5 100644 --- a/template/dockerfiles/javascript/draft.yaml +++ b/template/dockerfiles/javascript/draft.yaml @@ -4,12 +4,12 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "14" description: "the version of node used in the application" diff --git a/template/dockerfiles/php/draft.yaml b/template/dockerfiles/php/draft.yaml index a0fe3a5f..6d8cd459 100644 --- a/template/dockerfiles/php/draft.yaml +++ b/template/dockerfiles/php/draft.yaml @@ -4,17 +4,17 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - BUILDERVERSION: + - name: "BUILDERVERSION" default: value: "1" description: "the version of composer installed during the build stage to be used by the application" exampleValues: ["1"] - VERSION: + - name: "VERSION" default: value: "7.1-apache" description: "the version of php used by the application" diff --git a/template/dockerfiles/python/draft.yaml b/template/dockerfiles/python/draft.yaml index bd6de934..1eb83607 100644 --- a/template/dockerfiles/python/draft.yaml +++ b/template/dockerfiles/python/draft.yaml @@ -4,17 +4,17 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "3" description: "the version of python used by the application" exampleValues: ["3.9", "3.8", "3.7", "3.6"] - ENTRYPOINT: + - name: "ENTRYPOINT" default: value: "app.py" description: "the entrypoint file of the repository" diff --git a/template/dockerfiles/ruby/draft.yaml b/template/dockerfiles/ruby/draft.yaml index 76fc4a57..91bf2eba 100644 --- a/template/dockerfiles/ruby/draft.yaml +++ b/template/dockerfiles/ruby/draft.yaml @@ -4,12 +4,12 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "3.1.2" description: "the version of ruby used by the application" diff --git a/template/dockerfiles/rust/draft.yaml b/template/dockerfiles/rust/draft.yaml index 05c270fb..bf526b4a 100644 --- a/template/dockerfiles/rust/draft.yaml +++ b/template/dockerfiles/rust/draft.yaml @@ -4,12 +4,12 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "1.70.0" description: "the version of rust used by the application" diff --git a/template/dockerfiles/swift/draft.yaml b/template/dockerfiles/swift/draft.yaml index 44151e68..bf0191bb 100644 --- a/template/dockerfiles/swift/draft.yaml +++ b/template/dockerfiles/swift/draft.yaml @@ -4,12 +4,12 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - PORT: + - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int - VERSION: + - name: "VERSION" default: value: "5.5" description: "the version of swift used by the application" diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index 48e0abbf..4d14b033 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -1,29 +1,29 @@ variables: - BRANCHNAME: + - name: "BRANCHNAME" description: "the Github branch to automatically deploy from" - RESOURCEGROUP: + - name: "RESOURCEGROUP" description: "the ACR resource group" - AZURECONTAINERREGISTRY: + - name: "AZURECONTAINERREGISTRY" description: "the Azure container registry name" - CONTAINERNAME: + - name: "CONTAINERNAME" description: "the container image name" - CLUSTERNAME: + - name: "CLUSTERNAME" description: "the AKS cluster name" - BUILDCONTEXTPATH: + - name: "BUILDCONTEXTPATH" default: value: "." description: "the path to the Docker build context" - CHARTPATH: + - name: "CHARTPATH" default: disablePrompt: true value: "./charts" description: "the path to the Helm chart" - CHARTOVERRIDEPATH: + - name: "CHARTOVERRIDEPATH" default: disablePrompt: true value: "./charts/production.yaml" description: "the path to the Helm chart override file" - CHARTOVERRIDES: + - name: "CHARTOVERRIDES" default: disablePrompt: true value: "replicas:2" diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index 000d6d4a..01df153a 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -1,20 +1,20 @@ variables: - BRANCHNAME: + - name: "BRANCHNAME" description: "the Github branch to automatically deploy from" - RESOURCEGROUP: + - name: "RESOURCEGROUP" description: "the ACR resource group" - AZURECONTAINERREGISTRY: + - name: "AZURECONTAINERREGISTRY" description: "the Azure container registry name" - CONTAINERNAME: + - name: "CONTAINERNAME" description: "the container image name" - CLUSTERNAME: + - name: "CLUSTERNAME" description: "the AKS cluster name" - KUSTOMIZEPATH: + - name: "KUSTOMIZEPATH" default: disablePrompt: true value: "./overlays/production" description: "the path to the Kustomize directory" - BUILDCONTEXTPATH: + - name: "BUILDCONTEXTPATH" default: value: "." description: "the path to the Docker build context" \ No newline at end of file diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index b5bdd51d..beb109cd 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -1,20 +1,20 @@ variables: - BRANCHNAME: + - name: "BRANCHNAME" description: "the Github branch to automatically deploy from" - RESOURCEGROUP: + - name: "RESOURCEGROUP" description: "the ACR resource group" - AZURECONTAINERREGISTRY: + - name: "AZURECONTAINERREGISTRY" description: "the Azure container registry name" - CONTAINERNAME: + - name: "CONTAINERNAME" description: "the container image name" - CLUSTERNAME: + - name: "CLUSTERNAME" description: "the AKS cluster name" - DEPLOYMENTMANIFESTPATH: + - name: "DEPLOYMENTMANIFESTPATH" default: disablePrompt: true value: "./manifests" description: "the path to the Kubernetes deployment manifest" - BUILDCONTEXTPATH: + - name: "BUILDCONTEXTPATH" default: value: "." description: "the path to the Docker build context" \ No newline at end of file From 2c45d46495934d23cb28247967ebf0bfe9dc51bb Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 15:17:36 -0400 Subject: [PATCH 18/44] cleaned up templates --- template/dockerfiles/gradle/draft.yaml | 10 +++++----- .../workflows/azure-kubernetes-service-helm.yml | 7 ++++--- template/workflows/helm/draft.yaml | 5 ----- .../workflows/azure-kubernetes-service-kustomize.yml | 4 ++-- .../.github/workflows/azure-kubernetes-service.yml | 4 ++-- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/template/dockerfiles/gradle/draft.yaml b/template/dockerfiles/gradle/draft.yaml index 100aeef6..c031c8dd 100644 --- a/template/dockerfiles/gradle/draft.yaml +++ b/template/dockerfiles/gradle/draft.yaml @@ -4,16 +4,16 @@ nameOverrides: - path: "dockerignore" prefix: "." variables: - - name: "BUILDERVERSION" - default: - value: "jdk21" - description: "the version of gradle used during the builder stage to generate the executable" - exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] - name: "PORT" default: value: "80" description: "the port exposed in the application" type: int + - name: "BUILDERVERSION" + default: + value: "jdk21" + description: "the version of gradle used during the builder stage to generate the executable" + exampleValues: ["jdk8","jdk11","jdk17","jdk19","jdk21"] - name: "VERSION" default: value: "21-jre" diff --git a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml index 0324d454..7191f706 100644 --- a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml +++ b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml @@ -32,7 +32,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: "Build and deploy an app to AKS with Helm" +name: Build and deploy an app to AKS with Helm on: push: @@ -70,7 +70,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} . deploy: permissions: actions: read @@ -112,7 +112,8 @@ jobs: renderEngine: "helm" helmChart: ${{ env.CHART_PATH }} overrideFiles: ${{ env.CHART_OVERRIDE_PATH }} - overrides: ${{ env.CHART_OVERRIDES }} + overrides: | + replicas:2 helm-version: "latest" id: bake diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index 4d14b033..259275fd 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -23,9 +23,4 @@ variables: disablePrompt: true value: "./charts/production.yaml" description: "the path to the Helm chart override file" - - name: "CHARTOVERRIDES" - default: - disablePrompt: true - value: "replicas:2" - description: "the Helm chart overrides" \ No newline at end of file diff --git a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml index 77fdb4f1..8b49876e 100644 --- a/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml +++ b/template/workflows/kustomize/.github/workflows/azure-kubernetes-service-kustomize.yml @@ -31,7 +31,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: "Build and deploy an app to AKS" +name: Build and deploy an app to AKS with Kustomize on: push: @@ -67,7 +67,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} . deploy: permissions: actions: read diff --git a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml index 971cb43c..ca1b83cc 100644 --- a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml +++ b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml @@ -27,7 +27,7 @@ # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login -name: "Build and deploy an app to AKS" +name: Build and deploy an app to AKS on: push: @@ -63,7 +63,7 @@ jobs: # Builds and pushes an image up to your Azure Container Registry - name: Build and push image to ACR run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} ${{ env.BUILD_CONTEXT_PATH }} + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.RESOURCE_GROUP }} . deploy: permissions: actions: read From 9076e2f5e75314c523ba93c364bbb668d74ab45b Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 16:02:54 -0400 Subject: [PATCH 19/44] added GenerateWorkflowBytes() and VariableIdxMap() --- pkg/config/draftconfig.go | 26 ++++++++++++++++++++------ pkg/osutil/osutil.go | 8 ++++---- pkg/osutil/osutil_test.go | 2 +- pkg/workflows/workflows.go | 30 ++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 930f9def..40d44e41 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -2,6 +2,7 @@ package config import ( "errors" + "fmt" log "github.com/sirupsen/logrus" ) @@ -89,13 +90,26 @@ type TemplateVariableRecorder interface { } func (d *DraftConfig) VariableMap() (map[string]string, error) { - varMap := make(map[string]string) + envArgs := make(map[string]string) + for _, variable := range d.Variables { - if variable.Value == "" { - return nil, errors.New("variable " + variable.Name + " has no default value") - } - varMap[variable.Name] = variable.Value + envArgs[variable.Name] = variable.Value + } + + err := d.ApplyDefaultVariables(envArgs) + if err != nil { + return nil, fmt.Errorf("creating variable map: %w", err) + } + + return envArgs, nil +} + +func (d *DraftConfig) VariableIdxMap() map[string]int { + varIdxMap := make(map[string]int) + + for i, variable := range d.Variables { + varIdxMap[variable.Name] = i } - return varMap, nil + return varIdxMap } diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index eab99aea..7e7ea8d4 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -107,12 +107,12 @@ func CopyDir( return err } } else { - fileContent, err := replaceTemplateVariables(fileSys, srcPath, customInputs) + fileContent, err := ReplaceTemplateVariables(fileSys, srcPath, customInputs) if err != nil { return err } - if err = checkAllVariablesSubstituted(string(fileContent)); err != nil { + if err = CheckAllVariablesSubstituted(string(fileContent)); err != nil { return fmt.Errorf("error substituting file %s: %w", srcPath, err) } @@ -131,7 +131,7 @@ If any draft variables are found, an error is returned. Draft variables are defined as a string of non-whitespace characters starting with a non-period character wrapped in double curly braces. The non-period first character constraint is used to avoid matching helm template functions. */ -func checkAllVariablesSubstituted(fileContent string) error { +func CheckAllVariablesSubstituted(fileContent string) error { if unsubstitutedVars := draftVariableRegex.FindAllString(fileContent, -1); len(unsubstitutedVars) > 0 { unsubstitutedVarsString := strings.Join(unsubstitutedVars, ", ") return fmt.Errorf("unsubstituted variable: %s", unsubstitutedVarsString) @@ -139,7 +139,7 @@ func checkAllVariablesSubstituted(fileContent string) error { return nil } -func replaceTemplateVariables(fileSys fs.FS, srcPath string, customInputs map[string]string) ([]byte, error) { +func ReplaceTemplateVariables(fileSys fs.FS, srcPath string, customInputs map[string]string) ([]byte, error) { file, err := fs.ReadFile(fileSys, srcPath) if err != nil { return nil, err diff --git a/pkg/osutil/osutil_test.go b/pkg/osutil/osutil_test.go index ed108062..8536a77a 100644 --- a/pkg/osutil/osutil_test.go +++ b/pkg/osutil/osutil_test.go @@ -110,7 +110,7 @@ func TestAllVariablesSubstituted(t *testing.T) { for _, test := range tests { t.Run(test.String, func(t *testing.T) { - err := checkAllVariablesSubstituted(test.String) + err := CheckAllVariablesSubstituted(test.String) didError := err != nil assert.Equal(t, test.ExpectError, didError) }) diff --git a/pkg/workflows/workflows.go b/pkg/workflows/workflows.go index 1bc4b851..f11bbc66 100644 --- a/pkg/workflows/workflows.go +++ b/pkg/workflows/workflows.go @@ -20,6 +20,7 @@ import ( "github.com/Azure/draft/pkg/embedutils" "github.com/Azure/draft/pkg/osutil" "github.com/Azure/draft/pkg/templatewriter" + "github.com/Azure/draft/template" ) const ( @@ -187,3 +188,32 @@ func (w *Workflows) CreateWorkflowFiles(deployType string, customInputs map[stri return nil } + +func GenerateWorkflowBytes(draftConfig *config.DraftConfig, deployType string) ([]byte, error) { + envArgs, err := draftConfig.VariableMap() + if err != nil { + return nil, fmt.Errorf("generate workflow bytes: %w", err) + } + + var srcPath string + + switch deployType { + case "helm": + srcPath = "workflow/helm/.github/workflows/azure-kubernetes-service-helm.yml" + case "manifests": + srcPath = "workflow/manifests/.github/workflows/azure-kubernetes-service.yml" + default: + return nil, errors.New("unsupported deploy type") + } + + workflowBytes, err := osutil.ReplaceTemplateVariables(template.Workflows, srcPath, envArgs) + if err != nil { + return nil, fmt.Errorf("replace template variables: %w", err) + } + + if err = osutil.CheckAllVariablesSubstituted(string(workflowBytes)); err != nil { + return nil, fmt.Errorf("check all variables substituted: %w", err) + } + + return workflowBytes, nil +} From e38f13f108f59cd54be4a4df8aa83e43a4dcd36a Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 16:04:49 -0400 Subject: [PATCH 20/44] moving stuff into a future PR --- pkg/config/draftconfig.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 930f9def..982d7aba 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -26,7 +26,6 @@ type BuilderVar struct { Description string `yaml:"description"` ExampleValues []string `yaml:"exampleValues"` Type string `yaml:"type"` - Value string `yaml:"value"` } type BuilderVarDefault struct { @@ -87,15 +86,3 @@ func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) erro type TemplateVariableRecorder interface { Record(key, value string) } - -func (d *DraftConfig) VariableMap() (map[string]string, error) { - varMap := make(map[string]string) - for _, variable := range d.Variables { - if variable.Value == "" { - return nil, errors.New("variable " + variable.Name + " has no default value") - } - varMap[variable.Name] = variable.Value - } - - return varMap, nil -} From 8c792fb08414c71269b3783f6e75283c8cd14406 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 17:22:29 -0400 Subject: [PATCH 21/44] fixed ApplyDefaultVariables() --- pkg/config/draftconfig.go | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 982d7aba..312b5c56 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -67,21 +67,39 @@ func (d *DraftConfig) GetNameOverride(path string) string { } // ApplyDefaultVariables will apply the defaults to variables that are not already set -func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) error { +func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) error { for _, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling - if val, ok := customConfig[variable.Name]; !ok || val == "" { - if variable.Default.Value == "" { - return errors.New("variable " + variable.Name + " has no default value") + if customInputs[variable.Name] == "" { + if variable.Default.ReferenceVar != "" { + customInputs[variable.Name] = d.RecurseReferenceVars(variable, customInputs, make(map[string]int)) + log.Infof("Variable %s defaulting to value %s", variable.Name, customInputs[variable.Name]) + } + + if customInputs[variable.Name] == "" { + if variable.Default.Value != "" { + log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Default.Value) + customInputs[variable.Name] = variable.Default.Value + } else { + return errors.New("variable " + variable.Name + " has no default value") + } } - log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Default.Value) - customConfig[variable.Name] = variable.Default.Value } } return nil } +func (d *DraftConfig) RecurseReferenceVars(variable BuilderVar, customInputs map[string]string, varIdxMap map[string]int) string { + if customInputs[variable.Default.ReferenceVar] != "" { + return customInputs[variable.Default.ReferenceVar] + } else if variable.Default.ReferenceVar != "" { + return d.RecurseReferenceVars(d.Variables[varIdxMap[variable.Default.ReferenceVar]], customInputs, varIdxMap) + } + + return variable.Default.Value +} + // TemplateVariableRecorder is an interface for recording variables that are used read using draft configs type TemplateVariableRecorder interface { Record(key, value string) From d88b3dad15cfc525ed6b5723ff02c51ec196ab9b Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 17:24:59 -0400 Subject: [PATCH 22/44] wip --- pkg/config/draftconfig.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 312b5c56..1ed4c3a5 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -68,11 +68,13 @@ func (d *DraftConfig) GetNameOverride(path string) string { // ApplyDefaultVariables will apply the defaults to variables that are not already set func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) error { + varIdxMap := d.VariableIdxMap() + for _, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling if customInputs[variable.Name] == "" { if variable.Default.ReferenceVar != "" { - customInputs[variable.Name] = d.RecurseReferenceVars(variable, customInputs, make(map[string]int)) + customInputs[variable.Name] = d.RecurseReferenceVars(variable, customInputs, varIdxMap) log.Infof("Variable %s defaulting to value %s", variable.Name, customInputs[variable.Name]) } @@ -100,6 +102,16 @@ func (d *DraftConfig) RecurseReferenceVars(variable BuilderVar, customInputs map return variable.Default.Value } +func (d *DraftConfig) VariableIdxMap() map[string]int { + varIdxMap := make(map[string]int) + + for i, variable := range d.Variables { + varIdxMap[variable.Name] = i + } + + return varIdxMap +} + // TemplateVariableRecorder is an interface for recording variables that are used read using draft configs type TemplateVariableRecorder interface { Record(key, value string) From bf1d7163c8e8cd6a0d782025a769dbab3b24d9d5 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 18:07:16 -0400 Subject: [PATCH 23/44] wip --- pkg/config/draftconfig.go | 12 +++--- pkg/prompts/prompts.go | 25 ++++++------ pkg/prompts/prompts_test.go | 76 ++++++++++++++++++++++--------------- 3 files changed, 64 insertions(+), 49 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 1ed4c3a5..c49a67ca 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -68,13 +68,13 @@ func (d *DraftConfig) GetNameOverride(path string) string { // ApplyDefaultVariables will apply the defaults to variables that are not already set func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) error { - varIdxMap := d.VariableIdxMap() + varIdxMap := VariableIdxMap(d.Variables) for _, variable := range d.Variables { // handle where variable is not set or is set to an empty string from cli handling if customInputs[variable.Name] == "" { if variable.Default.ReferenceVar != "" { - customInputs[variable.Name] = d.RecurseReferenceVars(variable, customInputs, varIdxMap) + customInputs[variable.Name] = RecurseReferenceVars(d.Variables, variable, customInputs, varIdxMap) log.Infof("Variable %s defaulting to value %s", variable.Name, customInputs[variable.Name]) } @@ -92,20 +92,20 @@ func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) erro return nil } -func (d *DraftConfig) RecurseReferenceVars(variable BuilderVar, customInputs map[string]string, varIdxMap map[string]int) string { +func RecurseReferenceVars(variables []BuilderVar, variable BuilderVar, customInputs map[string]string, varIdxMap map[string]int) string { if customInputs[variable.Default.ReferenceVar] != "" { return customInputs[variable.Default.ReferenceVar] } else if variable.Default.ReferenceVar != "" { - return d.RecurseReferenceVars(d.Variables[varIdxMap[variable.Default.ReferenceVar]], customInputs, varIdxMap) + return RecurseReferenceVars(variables, variables[varIdxMap[variable.Default.ReferenceVar]], customInputs, varIdxMap) } return variable.Default.Value } -func (d *DraftConfig) VariableIdxMap() map[string]int { +func VariableIdxMap(variables []BuilderVar) map[string]int { varIdxMap := make(map[string]int) - for i, variable := range d.Variables { + for i, variable := range variables { varIdxMap[variable.Name] = i } diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 8d401f86..35e95fad 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -20,18 +20,18 @@ const defaultAppName = "my-app" // Function to get current directory name var getCurrentDirNameFunc = getCurrentDirName -func RunPromptsFromConfig(config *config.DraftConfig) (map[string]string, error) { - return RunPromptsFromConfigWithSkips(config, []string{}) +func RunPromptsFromConfig(draftConfig *config.DraftConfig) (map[string]string, error) { + return RunPromptsFromConfigWithSkips(draftConfig, []string{}) } -func RunPromptsFromConfigWithSkips(config *config.DraftConfig, varsToSkip []string) (map[string]string, error) { - return RunPromptsFromConfigWithSkipsIO(config, varsToSkip, nil, nil) +func RunPromptsFromConfigWithSkips(draftConfig *config.DraftConfig, varsToSkip []string) (map[string]string, error) { + return RunPromptsFromConfigWithSkipsIO(draftConfig, varsToSkip, nil, nil) } -// RunPromptsFromConfigWithSkipsIO runs the prompts for the given config +// RunPromptsFromConfigWithSkipsIO runs the prompts for the given draftConfig // skipping any variables in varsToSkip or where the BuilderVar.IsPromptDisabled is true. // If Stdin or Stdout are nil, the default values will be used. -func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []string, Stdin io.ReadCloser, Stdout io.WriteCloser) (map[string]string, error) { +func RunPromptsFromConfigWithSkipsIO(draftConfig *config.DraftConfig, varsToSkip []string, Stdin io.ReadCloser, Stdout io.WriteCloser) (map[string]string, error) { skipMap := make(map[string]interface{}) for _, v := range varsToSkip { skipMap[v] = interface{}(nil) @@ -39,7 +39,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st inputs := make(map[string]string) - for _, variable := range config.Variables { + for _, variable := range draftConfig.Variables { if val, ok := skipMap[variable.Name]; ok && val != "" { log.Debugf("Skipping prompt for %s", variable.Name) continue @@ -47,7 +47,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st if variable.Default.IsPromptDisabled { log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", variable.Name) - noPromptDefaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) + noPromptDefaultValue := GetVariableDefaultValue(variable.Name, draftConfig, variable, inputs) if noPromptDefaultValue == "" { return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", variable.Name) } @@ -64,7 +64,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st } inputs[variable.Name] = input } else { - defaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) + defaultValue := GetVariableDefaultValue(variable.Name, draftConfig, variable, inputs) stringInput, err := RunDefaultableStringPrompt(variable.Name, defaultValue, variable, nil, Stdin, Stdout) if err != nil { @@ -78,7 +78,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st } // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal Variable.DefaultValue in that order. -func GetVariableDefaultValue(variableName string, variable config.BuilderVar, inputs map[string]string) string { +func GetVariableDefaultValue(variableName string, draftConfig *config.DraftConfig, variable config.BuilderVar, inputs map[string]string) string { defaultValue := "" if variableName == "APPNAME" { @@ -93,8 +93,9 @@ func GetVariableDefaultValue(variableName string, variable config.BuilderVar, in defaultValue = variable.Default.Value log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) - if variable.Default.ReferenceVar != "" && inputs[variable.Default.ReferenceVar] != "" { - defaultValue = inputs[variable.Default.ReferenceVar] + if variable.Default.ReferenceVar != "" { + varIdxMap := config.VariableIdxMap(draftConfig.Variables) + defaultValue = config.RecurseReferenceVars(draftConfig.Variables, draftConfig.Variables[varIdxMap[variable.Default.ReferenceVar]], inputs, varIdxMap) log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variable.Default.ReferenceVar) } diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index 323cc8a8..35f348fc 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -11,43 +11,52 @@ func TestGetVariableDefaultValue(t *testing.T) { tests := []struct { testName string variableName string - variables map[string]config.BuilderVar + draftConfig config.DraftConfig inputs map[string]string want string }{ { testName: "basicLiteralExtractDefault", variableName: "var1", - variables: map[string]config.BuilderVar{ - "var1": { - Default: config.BuilderVarDefault{ - Value: "default-value-1", + draftConfig: config.DraftConfig{ + Variables: []config.BuilderVar{ + { + Name: "var1", + Default: config.BuilderVarDefault{ + Value: "default-value-1", + }, }, - }, - "var2": { - Default: config.BuilderVarDefault{ - Value: "default-value-2", + { + Name: "var2", + Default: config.BuilderVarDefault{ + Value: "default-value-2", + }, }, }, }, inputs: map[string]string{}, want: "default-value-1", }, - { - testName: "noDefaultIsEmptyString", - variableName: "var1", - variables: map[string]config.BuilderVar{}, - inputs: map[string]string{}, - want: "", - }, + // { + // testName: "noDefaultIsEmptyString", + // variableName: "var1", + // draftConfig: config.DraftConfig{ + // Variables: []config.BuilderVar{}, + // }, + // inputs: map[string]string{}, + // want: "", + // }, { testName: "referenceTakesPrecedenceOverLiteral", variableName: "var1", - variables: map[string]config.BuilderVar{ - "var1": { - Default: config.BuilderVarDefault{ - ReferenceVar: "var2", - Value: "not-this-value", + draftConfig: config.DraftConfig{ + Variables: []config.BuilderVar{ + { + Name: "var1", + Default: config.BuilderVarDefault{ + ReferenceVar: "var2", + Value: "not-this-value", + }, }, }, }, @@ -58,16 +67,20 @@ func TestGetVariableDefaultValue(t *testing.T) { }, { testName: "forwardReferencesAreIgnored", variableName: "beforeVar", - variables: map[string]config.BuilderVar{ - "beforeVar": { - Default: config.BuilderVarDefault{ - ReferenceVar: "afterVar", - Value: "before-default-value", + draftConfig: config.DraftConfig{ + Variables: []config.BuilderVar{ + { + Name: "beforeVar", + Default: config.BuilderVarDefault{ + ReferenceVar: "afterVar", + Value: "before-default-value", + }, }, - }, - "afterVar": { - Default: config.BuilderVarDefault{ - Value: "not-this-value", + { + Name: "afterVar", + Default: config.BuilderVarDefault{ + Value: "not-this-value", + }, }, }, }, @@ -77,7 +90,8 @@ func TestGetVariableDefaultValue(t *testing.T) { } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - if got := GetVariableDefaultValue(tt.variableName, tt.variables[tt.variableName], tt.inputs); got != tt.want { + varIdxMap := config.VariableIdxMap(tt.draftConfig.Variables) + if got := GetVariableDefaultValue(tt.variableName, &tt.draftConfig, tt.draftConfig.Variables[varIdxMap[tt.variableName]], tt.inputs); got != tt.want { t.Errorf("GetVariableDefaultValue() = %v, want %v", got, tt.want) } }) From 7e6614ecad9e3e95e0fa6eedd19f29f0993a7362 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Fri, 21 Jun 2024 18:16:21 -0400 Subject: [PATCH 24/44] updated tests --- pkg/config/draftconfig.go | 10 ++++++++++ pkg/prompts/prompts_test.go | 33 ++++++++++++++++----------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 982d7aba..9950e6b0 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -82,6 +82,16 @@ func (d *DraftConfig) ApplyDefaultVariables(customConfig map[string]string) erro return nil } +func VariableIdxMap(variables []BuilderVar) map[string]int { + varIdxMap := make(map[string]int) + + for i, variable := range variables { + varIdxMap[variable.Name] = i + } + + return varIdxMap +} + // TemplateVariableRecorder is an interface for recording variables that are used read using draft configs type TemplateVariableRecorder interface { Record(key, value string) diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index 323cc8a8..f6653d57 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -11,20 +11,22 @@ func TestGetVariableDefaultValue(t *testing.T) { tests := []struct { testName string variableName string - variables map[string]config.BuilderVar + variables []config.BuilderVar inputs map[string]string want string }{ { testName: "basicLiteralExtractDefault", variableName: "var1", - variables: map[string]config.BuilderVar{ - "var1": { + variables: []config.BuilderVar{ + { + Name: "var1", Default: config.BuilderVarDefault{ Value: "default-value-1", }, }, - "var2": { + { + Name: "var2", Default: config.BuilderVarDefault{ Value: "default-value-2", }, @@ -33,18 +35,12 @@ func TestGetVariableDefaultValue(t *testing.T) { inputs: map[string]string{}, want: "default-value-1", }, - { - testName: "noDefaultIsEmptyString", - variableName: "var1", - variables: map[string]config.BuilderVar{}, - inputs: map[string]string{}, - want: "", - }, { testName: "referenceTakesPrecedenceOverLiteral", variableName: "var1", - variables: map[string]config.BuilderVar{ - "var1": { + variables: []config.BuilderVar{ + { + Name: "var1", Default: config.BuilderVarDefault{ ReferenceVar: "var2", Value: "not-this-value", @@ -58,14 +54,16 @@ func TestGetVariableDefaultValue(t *testing.T) { }, { testName: "forwardReferencesAreIgnored", variableName: "beforeVar", - variables: map[string]config.BuilderVar{ - "beforeVar": { + variables: []config.BuilderVar{ + { + Name: "beforeVar", Default: config.BuilderVarDefault{ ReferenceVar: "afterVar", Value: "before-default-value", }, }, - "afterVar": { + { + Name: "afterVar", Default: config.BuilderVarDefault{ Value: "not-this-value", }, @@ -77,7 +75,8 @@ func TestGetVariableDefaultValue(t *testing.T) { } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - if got := GetVariableDefaultValue(tt.variableName, tt.variables[tt.variableName], tt.inputs); got != tt.want { + varIdxMap := config.VariableIdxMap(tt.variables) + if got := GetVariableDefaultValue(tt.variableName, tt.variables[varIdxMap[tt.variableName]], tt.inputs); got != tt.want { t.Errorf("GetVariableDefaultValue() = %v, want %v", got, tt.want) } }) From a80a6d562fa30fc4bb01b0651596fcf778029dff Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Sun, 23 Jun 2024 13:28:13 -0400 Subject: [PATCH 25/44] added back noDefaultIsEmptyString test --- pkg/prompts/prompts_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index f6653d57..adc5767e 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -35,6 +35,17 @@ func TestGetVariableDefaultValue(t *testing.T) { inputs: map[string]string{}, want: "default-value-1", }, + { + testName: "noDefaultIsEmptyString", + variableName: "var1", + variables: []config.BuilderVar{ + { + Name: "var1", + }, + }, + inputs: map[string]string{}, + want: "", + }, { testName: "referenceTakesPrecedenceOverLiteral", variableName: "var1", From 148eba242921b151d209c0ead708e5ae469428c5 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Sun, 23 Jun 2024 13:32:56 -0400 Subject: [PATCH 26/44] updating prompts_tests --- pkg/prompts/prompts_test.go | 67 ++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index 35f348fc..88e5c166 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -37,15 +37,19 @@ func TestGetVariableDefaultValue(t *testing.T) { inputs: map[string]string{}, want: "default-value-1", }, - // { - // testName: "noDefaultIsEmptyString", - // variableName: "var1", - // draftConfig: config.DraftConfig{ - // Variables: []config.BuilderVar{}, - // }, - // inputs: map[string]string{}, - // want: "", - // }, + { + testName: "noDefaultIsEmptyString", + variableName: "var1", + draftConfig: config.DraftConfig{ + Variables: []config.BuilderVar{ + { + Name: "var1", + }, + }, + }, + inputs: map[string]string{}, + want: "", + }, { testName: "referenceTakesPrecedenceOverLiteral", variableName: "var1", @@ -64,29 +68,30 @@ func TestGetVariableDefaultValue(t *testing.T) { "var2": "this-value", }, want: "this-value", - }, { - testName: "forwardReferencesAreIgnored", - variableName: "beforeVar", - draftConfig: config.DraftConfig{ - Variables: []config.BuilderVar{ - { - Name: "beforeVar", - Default: config.BuilderVarDefault{ - ReferenceVar: "afterVar", - Value: "before-default-value", - }, - }, - { - Name: "afterVar", - Default: config.BuilderVarDefault{ - Value: "not-this-value", - }, - }, - }, - }, - inputs: map[string]string{}, - want: "before-default-value", }, + // { + // testName: "forwardReferencesAreIgnored", + // variableName: "beforeVar", + // draftConfig: config.DraftConfig{ + // Variables: []config.BuilderVar{ + // { + // Name: "beforeVar", + // Default: config.BuilderVarDefault{ + // ReferenceVar: "afterVar", + // Value: "before-default-value", + // }, + // }, + // { + // Name: "afterVar", + // Default: config.BuilderVarDefault{ + // Value: "not-this-value", + // }, + // }, + // }, + // }, + // inputs: map[string]string{}, + // want: "before-default-value", + // }, } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { From 9fb8005e956df5738b13fcf1de10d6e84e3db47a Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Mon, 24 Jun 2024 13:49:02 -0400 Subject: [PATCH 27/44] rolled back changes to prompts.go --- pkg/prompts/prompts.go | 11 ++++----- pkg/prompts/prompts_test.go | 48 ++++++++++++++++++------------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 35e95fad..c4644302 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -47,7 +47,7 @@ func RunPromptsFromConfigWithSkipsIO(draftConfig *config.DraftConfig, varsToSkip if variable.Default.IsPromptDisabled { log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", variable.Name) - noPromptDefaultValue := GetVariableDefaultValue(variable.Name, draftConfig, variable, inputs) + noPromptDefaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) if noPromptDefaultValue == "" { return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", variable.Name) } @@ -64,7 +64,7 @@ func RunPromptsFromConfigWithSkipsIO(draftConfig *config.DraftConfig, varsToSkip } inputs[variable.Name] = input } else { - defaultValue := GetVariableDefaultValue(variable.Name, draftConfig, variable, inputs) + defaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) stringInput, err := RunDefaultableStringPrompt(variable.Name, defaultValue, variable, nil, Stdin, Stdout) if err != nil { @@ -78,7 +78,7 @@ func RunPromptsFromConfigWithSkipsIO(draftConfig *config.DraftConfig, varsToSkip } // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal Variable.DefaultValue in that order. -func GetVariableDefaultValue(variableName string, draftConfig *config.DraftConfig, variable config.BuilderVar, inputs map[string]string) string { +func GetVariableDefaultValue(variableName string, variable config.BuilderVar, inputs map[string]string) string { defaultValue := "" if variableName == "APPNAME" { @@ -93,9 +93,8 @@ func GetVariableDefaultValue(variableName string, draftConfig *config.DraftConfi defaultValue = variable.Default.Value log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) - if variable.Default.ReferenceVar != "" { - varIdxMap := config.VariableIdxMap(draftConfig.Variables) - defaultValue = config.RecurseReferenceVars(draftConfig.Variables, draftConfig.Variables[varIdxMap[variable.Default.ReferenceVar]], inputs, varIdxMap) + if variable.Default.ReferenceVar != "" && inputs[variable.Default.ReferenceVar] != "" { + defaultValue = inputs[variable.Default.ReferenceVar] log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variable.Default.ReferenceVar) } diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index 88e5c166..7bb5a5e3 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -69,34 +69,34 @@ func TestGetVariableDefaultValue(t *testing.T) { }, want: "this-value", }, - // { - // testName: "forwardReferencesAreIgnored", - // variableName: "beforeVar", - // draftConfig: config.DraftConfig{ - // Variables: []config.BuilderVar{ - // { - // Name: "beforeVar", - // Default: config.BuilderVarDefault{ - // ReferenceVar: "afterVar", - // Value: "before-default-value", - // }, - // }, - // { - // Name: "afterVar", - // Default: config.BuilderVarDefault{ - // Value: "not-this-value", - // }, - // }, - // }, - // }, - // inputs: map[string]string{}, - // want: "before-default-value", - // }, + { + testName: "forwardReferencesAreIgnored", + variableName: "beforeVar", + draftConfig: config.DraftConfig{ + Variables: []config.BuilderVar{ + { + Name: "beforeVar", + Default: config.BuilderVarDefault{ + ReferenceVar: "afterVar", + Value: "before-default-value", + }, + }, + { + Name: "afterVar", + Default: config.BuilderVarDefault{ + Value: "not-this-value", + }, + }, + }, + }, + inputs: map[string]string{}, + want: "before-default-value", + }, } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { varIdxMap := config.VariableIdxMap(tt.draftConfig.Variables) - if got := GetVariableDefaultValue(tt.variableName, &tt.draftConfig, tt.draftConfig.Variables[varIdxMap[tt.variableName]], tt.inputs); got != tt.want { + if got := GetVariableDefaultValue(tt.variableName, tt.draftConfig.Variables[varIdxMap[tt.variableName]], tt.inputs); got != tt.want { t.Errorf("GetVariableDefaultValue() = %v, want %v", got, tt.want) } }) From e370432c1a58a5099ed42afa2f9a7b240daaf791 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Mon, 24 Jun 2024 13:56:29 -0400 Subject: [PATCH 28/44] got rid of variableName --- pkg/prompts/prompts.go | 18 +++++++++--------- pkg/prompts/prompts_test.go | 38 ++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/pkg/prompts/prompts.go b/pkg/prompts/prompts.go index 8d401f86..cc8bdf15 100644 --- a/pkg/prompts/prompts.go +++ b/pkg/prompts/prompts.go @@ -47,7 +47,7 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st if variable.Default.IsPromptDisabled { log.Debugf("Skipping prompt for %s as it has IsPromptDisabled=true", variable.Name) - noPromptDefaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) + noPromptDefaultValue := GetVariableDefaultValue(variable, inputs) if noPromptDefaultValue == "" { return nil, fmt.Errorf("IsPromptDisabled is true for %s but no default value was found", variable.Name) } @@ -64,9 +64,9 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st } inputs[variable.Name] = input } else { - defaultValue := GetVariableDefaultValue(variable.Name, variable, inputs) + defaultValue := GetVariableDefaultValue(variable, inputs) - stringInput, err := RunDefaultableStringPrompt(variable.Name, defaultValue, variable, nil, Stdin, Stdout) + stringInput, err := RunDefaultableStringPrompt(defaultValue, variable, nil, Stdin, Stdout) if err != nil { return nil, err } @@ -78,10 +78,10 @@ func RunPromptsFromConfigWithSkipsIO(config *config.DraftConfig, varsToSkip []st } // GetVariableDefaultValue returns the default value for a variable, if one is set in variableDefaults from a ReferenceVar or literal Variable.DefaultValue in that order. -func GetVariableDefaultValue(variableName string, variable config.BuilderVar, inputs map[string]string) string { +func GetVariableDefaultValue(variable config.BuilderVar, inputs map[string]string) string { defaultValue := "" - if variableName == "APPNAME" { + if variable.Name == "APPNAME" { dirName, err := getCurrentDirNameFunc() if err != nil { log.Errorf("Error retrieving current directory name: %s", err) @@ -92,10 +92,10 @@ func GetVariableDefaultValue(variableName string, variable config.BuilderVar, in } defaultValue = variable.Default.Value - log.Debugf("setting default value for %s to %s from variable default rule", variableName, defaultValue) + log.Debugf("setting default value for %s to %s from variable default rule", variable.Name, defaultValue) if variable.Default.ReferenceVar != "" && inputs[variable.Default.ReferenceVar] != "" { defaultValue = inputs[variable.Default.ReferenceVar] - log.Debugf("setting default value for %s to %s from referenceVar %s", variableName, defaultValue, variable.Default.ReferenceVar) + log.Debugf("setting default value for %s to %s from referenceVar %s", variable.Name, defaultValue, variable.Default.ReferenceVar) } return defaultValue @@ -157,7 +157,7 @@ func appNameValidator(name string) error { } // RunDefaultableStringPrompt runs a prompt for a string variable, returning the user string input for the prompt -func RunDefaultableStringPrompt(name, defaultValue string, customPrompt config.BuilderVar, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) { +func RunDefaultableStringPrompt(defaultValue string, customPrompt config.BuilderVar, validate func(string) error, Stdin io.ReadCloser, Stdout io.WriteCloser) (string, error) { if validate == nil { validate = NoBlankStringValidator } @@ -167,7 +167,7 @@ func RunDefaultableStringPrompt(name, defaultValue string, customPrompt config.B if input == "" { return nil } - if name == "APPNAME" { + if customPrompt.Name == "APPNAME" { if err := appNameValidator(input); err != nil { return err } diff --git a/pkg/prompts/prompts_test.go b/pkg/prompts/prompts_test.go index adc5767e..ffc54d58 100644 --- a/pkg/prompts/prompts_test.go +++ b/pkg/prompts/prompts_test.go @@ -9,15 +9,13 @@ import ( func TestGetVariableDefaultValue(t *testing.T) { tests := []struct { - testName string - variableName string - variables []config.BuilderVar - inputs map[string]string - want string + testName string + variables []config.BuilderVar + inputs map[string]string + want string }{ { - testName: "basicLiteralExtractDefault", - variableName: "var1", + testName: "basicLiteralExtractDefault", variables: []config.BuilderVar{ { Name: "var1", @@ -36,8 +34,7 @@ func TestGetVariableDefaultValue(t *testing.T) { want: "default-value-1", }, { - testName: "noDefaultIsEmptyString", - variableName: "var1", + testName: "noDefaultIsEmptyString", variables: []config.BuilderVar{ { Name: "var1", @@ -47,8 +44,7 @@ func TestGetVariableDefaultValue(t *testing.T) { want: "", }, { - testName: "referenceTakesPrecedenceOverLiteral", - variableName: "var1", + testName: "referenceTakesPrecedenceOverLiteral", variables: []config.BuilderVar{ { Name: "var1", @@ -62,9 +58,9 @@ func TestGetVariableDefaultValue(t *testing.T) { "var2": "this-value", }, want: "this-value", - }, { - testName: "forwardReferencesAreIgnored", - variableName: "beforeVar", + }, + { + testName: "forwardReferencesAreIgnored", variables: []config.BuilderVar{ { Name: "beforeVar", @@ -86,8 +82,7 @@ func TestGetVariableDefaultValue(t *testing.T) { } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - varIdxMap := config.VariableIdxMap(tt.variables) - if got := GetVariableDefaultValue(tt.variableName, tt.variables[varIdxMap[tt.variableName]], tt.inputs); got != tt.want { + if got := GetVariableDefaultValue(tt.variables[0], tt.inputs); got != tt.want { t.Errorf("GetVariableDefaultValue() = %v, want %v", got, tt.want) } }) @@ -97,7 +92,6 @@ func TestGetVariableDefaultValue(t *testing.T) { func TestRunStringPrompt(t *testing.T) { tests := []struct { testName string - variableName string prompt config.BuilderVar userInputs []string defaultValue string @@ -128,9 +122,9 @@ func TestRunStringPrompt(t *testing.T) { mockDirNameValue: "", }, { - testName: "appNameUsesDirName", - variableName: "APPNAME", + testName: "appNameUsesDirName", prompt: config.BuilderVar{ + Name: "APPNAME", Description: "app name", }, userInputs: []string{"\n"}, @@ -140,9 +134,9 @@ func TestRunStringPrompt(t *testing.T) { mockDirNameValue: "currentdir", }, { - testName: "invalidAppName", - variableName: "APPNAME", + testName: "invalidAppName", prompt: config.BuilderVar{ + Name: "APPNAME", Description: "app name", }, userInputs: []string{"--invalid-app-name\n"}, @@ -176,7 +170,7 @@ func TestRunStringPrompt(t *testing.T) { t.Errorf("Error closing inWriter: %v", err) } }() - got, err := RunDefaultableStringPrompt(tt.variableName, tt.defaultValue, tt.prompt, nil, inReader, nil) + got, err := RunDefaultableStringPrompt(tt.defaultValue, tt.prompt, nil, inReader, nil) if (err != nil) != tt.wantErr { t.Errorf("RunDefaultableStringPrompt() error = %v, wantErr %v", err, tt.wantErr) From 5706cbb3da5427762932290795a288a6eeb9ca8b Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Mon, 24 Jun 2024 14:16:28 -0400 Subject: [PATCH 29/44] cyclical recursion protection --- pkg/config/draftconfig.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index c49a67ca..8dcf3e92 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -2,6 +2,7 @@ package config import ( "errors" + "fmt" log "github.com/sirupsen/logrus" ) @@ -74,8 +75,12 @@ func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) erro // handle where variable is not set or is set to an empty string from cli handling if customInputs[variable.Name] == "" { if variable.Default.ReferenceVar != "" { - customInputs[variable.Name] = RecurseReferenceVars(d.Variables, variable, customInputs, varIdxMap) + defaultVal, err := recurseReferenceVars(d.Variables, variable, customInputs, varIdxMap, variable, true) + if err != nil { + return fmt.Errorf("apply default variables: %w", err) + } log.Infof("Variable %s defaulting to value %s", variable.Name, customInputs[variable.Name]) + customInputs[variable.Name] = defaultVal } if customInputs[variable.Name] == "" { @@ -92,14 +97,18 @@ func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) erro return nil } -func RecurseReferenceVars(variables []BuilderVar, variable BuilderVar, customInputs map[string]string, varIdxMap map[string]int) string { +func recurseReferenceVars(variables []BuilderVar, variable BuilderVar, customInputs map[string]string, varIdxMap map[string]int, variableCheck BuilderVar, isFirst bool) (string, error) { + if !isFirst && variable.Name == variableCheck.Name { + return "", errors.New("circular reference detected") + } + if customInputs[variable.Default.ReferenceVar] != "" { - return customInputs[variable.Default.ReferenceVar] + return customInputs[variable.Default.ReferenceVar], nil } else if variable.Default.ReferenceVar != "" { - return RecurseReferenceVars(variables, variables[varIdxMap[variable.Default.ReferenceVar]], customInputs, varIdxMap) + return recurseReferenceVars(variables, variables[varIdxMap[variable.Default.ReferenceVar]], customInputs, varIdxMap, variableCheck, false) } - return variable.Default.Value + return variable.Default.Value, nil } func VariableIdxMap(variables []BuilderVar) map[string]int { From f8652d2323bf1d8775a5b389591e6c10381f3bd2 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Mon, 24 Jun 2024 15:53:43 -0400 Subject: [PATCH 30/44] wip --- pkg/workflows/workflows.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/workflows/workflows.go b/pkg/workflows/workflows.go index f11bbc66..5d2b5df5 100644 --- a/pkg/workflows/workflows.go +++ b/pkg/workflows/workflows.go @@ -195,6 +195,10 @@ func GenerateWorkflowBytes(draftConfig *config.DraftConfig, deployType string) ( return nil, fmt.Errorf("generate workflow bytes: %w", err) } + if err = draftConfig.ApplyDefaultVariables(envArgs); err != nil { + return nil, fmt.Errorf("apply default variables: %w", err) + } + var srcPath string switch deployType { From bc488d679425281cbb6b31d8aba3dd5e254b123c Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Mon, 24 Jun 2024 16:37:27 -0400 Subject: [PATCH 31/44] added flags for new env args --- cmd/generate-workflow.go | 17 +++++--- pkg/workflows/workflowconfig.go | 53 ++++++++++++++++++------- template/workflows/helm/draft.yaml | 1 - template/workflows/kustomize/draft.yaml | 1 - template/workflows/manifests/draft.yaml | 1 - 5 files changed, 50 insertions(+), 23 deletions(-) diff --git a/cmd/generate-workflow.go b/cmd/generate-workflow.go index 22c75f07..1f122ab2 100644 --- a/cmd/generate-workflow.go +++ b/cmd/generate-workflow.go @@ -52,15 +52,20 @@ with draft on AKS. This command assumes the 'setup-gh' command has been run prop } f := cmd.Flags() - f.StringVarP(&gwCmd.workflowConfig.AksClusterName, "cluster-name", "c", emptyDefaultFlagValue, "specify the AKS cluster name") - f.StringVarP(&gwCmd.workflowConfig.AcrName, "registry-name", "r", emptyDefaultFlagValue, "specify the Azure container registry name") + f.StringVarP(&gwCmd.workflowConfig.WorkflowName, "workflow", "w", emptyDefaultFlagValue, "specify the Github workflow name") + f.StringVarP(&gwCmd.workflowConfig.BranchName, "branch", "b", emptyDefaultFlagValue, "specify the Github branch to automatically deploy from") + f.StringVar(&gwCmd.workflowConfig.AcrResourceGroup, "acr-resource-group", emptyDefaultFlagValue, "specify the Azure container registry resource group") + f.StringVarP(&gwCmd.workflowConfig.Acr, "registry-name", "r", emptyDefaultFlagValue, "specify the Azure container registry name") f.StringVar(&gwCmd.workflowConfig.ContainerName, "container-name", emptyDefaultFlagValue, "specify the container image name") - f.StringVarP(&gwCmd.workflowConfig.ResourceGroupName, "resource-group", "g", emptyDefaultFlagValue, "specify the Azure resource group of your AKS cluster") + f.StringVarP(&gwCmd.workflowConfig.ClusterResourceGroup, "cluster-resource-group", "g", emptyDefaultFlagValue, "specify the Azure resource group of your AKS cluster") + f.StringVarP(&gwCmd.workflowConfig.ClusterName, "cluster-name", "c", emptyDefaultFlagValue, "specify the AKS cluster name") + f.StringVar(&gwCmd.workflowConfig.Dockerfile, "dockerfile", emptyDefaultFlagValue, "specify the path to the Dockerfile") + f.StringVarP(&gwCmd.workflowConfig.BuildContextPath, "build-context-path", "x", emptyDefaultFlagValue, "specify the docker build context path") + f.StringVarP(&gwCmd.workflowConfig.Namespace, "namespace", "n", emptyDefaultFlagValue, "specify the Kubernetes namespace") + f.StringVarP(&gwCmd.workflowConfig.PrivateCluster, "private-cluster", "p", emptyDefaultFlagValue, "specify if the AKS cluster is private") f.StringVarP(&gwCmd.dest, "destination", "d", currentDirDefaultFlagValue, "specify the path to the project directory") - f.StringVarP(&gwCmd.workflowConfig.BranchName, "branch", "b", emptyDefaultFlagValue, "specify the Github branch to automatically deploy from") f.StringVar(&gwCmd.deployType, "deploy-type", emptyDefaultFlagValue, "specify the type of deployment") f.StringArrayVarP(&gwCmd.flagVariables, "variable", "", []string{}, "pass additional variables") - f.StringVarP(&gwCmd.workflowConfig.BuildContextPath, "build-context-path", "x", emptyDefaultFlagValue, "specify the docker build context path") gwCmd.templateWriter = &writers.LocalFSWriter{} return cmd } @@ -109,4 +114,4 @@ func (gwc *generateWorkflowCmd) generateWorkflows(dest string, deployType string maps.Copy(customInputs, flagValuesMap) return workflow.CreateWorkflowFiles(deployType, customInputs, templateWriter) -} \ No newline at end of file +} diff --git a/pkg/workflows/workflowconfig.go b/pkg/workflows/workflowconfig.go index 0752b941..ea884fde 100644 --- a/pkg/workflows/workflowconfig.go +++ b/pkg/workflows/workflowconfig.go @@ -1,39 +1,64 @@ package workflows type WorkflowConfig struct { - AcrName string - ContainerName string - ResourceGroupName string - AksClusterName string - BranchName string - BuildContextPath string + WorkflowName string + BranchName string + AcrResourceGroup string + Acr string + ContainerName string + ClusterResourceGroup string + ClusterName string + Dockerfile string + BuildContextPath string + Namespace string + PrivateCluster string } func (config *WorkflowConfig) SetFlagValuesToMap() map[string]string { flagValuesMap := make(map[string]string) - if config.AcrName != "" { - flagValuesMap["AZURECONTAINERREGISTRY"] = config.AcrName + if config.WorkflowName != "" { + flagValuesMap["WORKFLOWNAME"] = config.WorkflowName + } + + if config.BranchName != "" { + flagValuesMap["BRANCHNAME"] = config.BranchName + } + + if config.AcrResourceGroup != "" { + flagValuesMap["ACRRESOURCEGROUP"] = config.AcrResourceGroup + } + + if config.Acr != "" { + flagValuesMap["AZURECONTAINERREGISTRY"] = config.Acr } if config.ContainerName != "" { flagValuesMap["CONTAINERNAME"] = config.ContainerName } - if config.ResourceGroupName != "" { - flagValuesMap["RESOURCEGROUP"] = config.ResourceGroupName + if config.ClusterResourceGroup != "" { + flagValuesMap["RESOURCEGROUP"] = config.ClusterResourceGroup } - if config.AksClusterName != "" { - flagValuesMap["CLUSTERNAME"] = config.AksClusterName + if config.ClusterName != "" { + flagValuesMap["CLUSTERNAME"] = config.ClusterName } - if config.BranchName != "" { - flagValuesMap["BRANCHNAME"] = config.BranchName + if config.Dockerfile != "" { + flagValuesMap["DOCKERFILE"] = config.Dockerfile } if config.BuildContextPath != "" { flagValuesMap["BUILDCONTEXTPATH"] = config.BuildContextPath } + if config.Namespace != "" { + flagValuesMap["NAMESPACE"] = config.Namespace + } + + if config.PrivateCluster != "" { + flagValuesMap["PRIVATECLUSTER"] = config.PrivateCluster + } + return flagValuesMap } diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index b87b2753..674a0d27 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -17,7 +17,6 @@ variables: description: "the AKS cluster name" - name: "DOCKERFILE" default: - disablePrompt: true value: "./Dockerfile" description: "the path to the Dockerfile" - name: "BUILDCONTEXTPATH" diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index 6bff2fda..f0f5edb4 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -22,7 +22,6 @@ variables: description: "the path to the Kustomize directory" - name: "DOCKERFILE" default: - disablePrompt: true value: "./Dockerfile" description: "the path to the Dockerfile" - name: "BUILDCONTEXTPATH" diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index 4502833f..c4f41110 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -22,7 +22,6 @@ variables: description: "the path to the Kubernetes deployment manifest" - name: "DOCKERFILE" default: - disablePrompt: true value: "./Dockerfile" description: "the path to the Dockerfile" - name: "BUILDCONTEXTPATH" From 4be85f9debde092e991333a839c2b9578f3da44a Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Mon, 24 Jun 2024 16:48:47 -0400 Subject: [PATCH 32/44] added flags --- cmd/create.go | 24 +++++-------------- .../azure-kubernetes-service-helm.yml | 3 +-- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/cmd/create.go b/cmd/create.go index b0bfd1d0..4f57204f 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -292,7 +292,7 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan return err } } else { - inputs, err = validateConfigInputsToPrompts(langConfig.Variables, cc.createConfig.LanguageVariables) + inputs, err = validateConfigInputsToPrompts(langConfig, cc.createConfig.LanguageVariables) if err != nil { return err } @@ -330,7 +330,7 @@ func (cc *createCmd) createDeployment() error { if deployConfig == nil { return errors.New("invalid deployment type") } - customInputs, err = validateConfigInputsToPrompts(deployConfig.Variables, cc.createConfig.DeployVariables) + customInputs, err = validateConfigInputsToPrompts(deployConfig, cc.createConfig.DeployVariables) if err != nil { return err } @@ -464,7 +464,7 @@ func init() { rootCmd.AddCommand(newCreateCmd()) } -func validateConfigInputsToPrompts(required []config.BuilderVar, provided []UserInputs) (map[string]string, error) { +func validateConfigInputsToPrompts(draftConfig *config.DraftConfig, provided []UserInputs) (map[string]string, error) { customInputs := make(map[string]string) // set inputs to provided values @@ -472,23 +472,11 @@ func validateConfigInputsToPrompts(required []config.BuilderVar, provided []User customInputs[variable.Name] = variable.Value } - // fill in missing vars using variable default references - for _, variable := range required { - if customInputs[variable.Name] == "" && variable.Default.ReferenceVar != "" { - log.Debugf("variable %s is empty, using default referenceVar value from %s", variable.Name, variable.Default.ReferenceVar) - customInputs[variable.Name] = customInputs[variable.Default.ReferenceVar] - } - } - - // fill in missing vars using variable default values - for _, variable := range required { - if customInputs[variable.Name] == "" && variable.Default.Value != "" { - log.Debugf("variable %s is empty, using default value %s", variable.Name, variable.Default.Value) - customInputs[variable.Name] = variable.Default.Value - } + if err := draftConfig.ApplyDefaultVariables(customInputs); err != nil { + return nil, fmt.Errorf("validate config inputs to prompts: %w", err) } - for _, variable := range required { + for _, variable := range draftConfig.Variables { value, ok := customInputs[variable.Name] if !ok { return nil, fmt.Errorf("config missing required variable: %s with description: %s", variable.Name, variable.Description) diff --git a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml index e1178354..5952ff4c 100644 --- a/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml +++ b/template/workflows/helm/.github/workflows/azure-kubernetes-service-helm.yml @@ -116,8 +116,7 @@ jobs: renderEngine: "helm" helmChart: ${{ env.CHART_PATH }} overrideFiles: ${{ env.CHART_OVERRIDE_PATH }} - overrides: | - replicas:2 + overrides: ${{ env.CHART_OVERRIDES }} helm-version: "latest" id: bake From e9f4341557792d4cc277d07d5c79df15dc70e1e1 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 09:45:00 -0400 Subject: [PATCH 33/44] updating tests --- cmd/create_test.go | 36 ++--- cmd/generate-workflow.go | 2 +- .../azure-kubernetes-service-helm.yml | 132 ++++++++++++++++++ pkg/workflows/charts/production.yaml | 8 ++ pkg/workflows/workflows_test.go | 8 +- 5 files changed, 165 insertions(+), 21 deletions(-) create mode 100644 pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml create mode 100644 pkg/workflows/charts/production.yaml diff --git a/cmd/create_test.go b/cmd/create_test.go index bfcff610..5bdcd4e0 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -142,14 +142,16 @@ func TestInitConfig(t *testing.T) { } func TestValidateConfigInputsToPromptsPass(t *testing.T) { - required := []config.BuilderVar{ - { - Name: "REQUIRED_PROVIDED", - }, - { - Name: "REQUIRED_DEFAULTED", - Default: config.BuilderVarDefault{ - Value: "DEFAULT_VALUE", + required := config.DraftConfig{ + Variables: []config.BuilderVar{ + { + Name: "REQUIRED_PROVIDED", + }, + { + Name: "REQUIRED_DEFAULTED", + Default: config.BuilderVarDefault{ + Value: "DEFAULT_VALUE", + }, }, }, } @@ -157,25 +159,27 @@ func TestValidateConfigInputsToPromptsPass(t *testing.T) { {Name: "REQUIRED_PROVIDED", Value: "PROVIDED_VALUE"}, } - vars, err := validateConfigInputsToPrompts(required, provided) + vars, err := validateConfigInputsToPrompts(&required, provided) assert.True(t, err == nil) assert.Equal(t, vars["REQUIRED_DEFAULTED"], "DEFAULT_VALUE") } func TestValidateConfigInputsToPromptsMissing(t *testing.T) { - required := []config.BuilderVar{ - { - Name: "REQUIRED_PROVIDED", - }, - { - Name: "REQUIRED_MISSING", + required := config.DraftConfig{ + Variables: []config.BuilderVar{ + { + Name: "REQUIRED_PROVIDED", + }, + { + Name: "REQUIRED_MISSING", + }, }, } provided := []UserInputs{ {Name: "REQUIRED_PROVIDED"}, } - _, err := validateConfigInputsToPrompts(required, provided) + _, err := validateConfigInputsToPrompts(&required, provided) assert.NotNil(t, err) } diff --git a/cmd/generate-workflow.go b/cmd/generate-workflow.go index 1f122ab2..0af0de77 100644 --- a/cmd/generate-workflow.go +++ b/cmd/generate-workflow.go @@ -62,7 +62,7 @@ with draft on AKS. This command assumes the 'setup-gh' command has been run prop f.StringVar(&gwCmd.workflowConfig.Dockerfile, "dockerfile", emptyDefaultFlagValue, "specify the path to the Dockerfile") f.StringVarP(&gwCmd.workflowConfig.BuildContextPath, "build-context-path", "x", emptyDefaultFlagValue, "specify the docker build context path") f.StringVarP(&gwCmd.workflowConfig.Namespace, "namespace", "n", emptyDefaultFlagValue, "specify the Kubernetes namespace") - f.StringVarP(&gwCmd.workflowConfig.PrivateCluster, "private-cluster", "p", emptyDefaultFlagValue, "specify if the AKS cluster is private") + f.StringVar(&gwCmd.workflowConfig.PrivateCluster, "private-cluster", emptyDefaultFlagValue, "specify if the AKS cluster is private") f.StringVarP(&gwCmd.dest, "destination", "d", currentDirDefaultFlagValue, "specify the path to the project directory") f.StringVar(&gwCmd.deployType, "deploy-type", emptyDefaultFlagValue, "specify the type of deployment") f.StringArrayVarP(&gwCmd.flagVariables, "variable", "", []string{}, "pass additional variables") diff --git a/pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml b/pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml new file mode 100644 index 00000000..65624bde --- /dev/null +++ b/pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml @@ -0,0 +1,132 @@ +# This workflow will build and push an application to a Azure Kubernetes Service (AKS) cluster when you push your code +# +# This workflow assumes you have already created the target AKS cluster and have created an Azure Container Registry (ACR) +# The ACR should be attached to the AKS cluster +# For instructions see: +# - https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal +# - https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal +# - https://learn.microsoft.com/en-us/azure/aks/cluster-container-registry-integration?tabs=azure-cli#configure-acr-integration-for-existing-aks-clusters +# - https://github.com/Azure/aks-create-action +# +# To configure this workflow: +# +# 1. Set the following secrets in your repository (instructions for getting these +# https://docs.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-cli%2Clinux)): +# - AZURE_CLIENT_ID +# - AZURE_TENANT_ID +# - AZURE_SUBSCRIPTION_ID +# +# 2. Set the following environment variables (or replace the values below): +# - AZURE_CONTAINER_REGISTRY (name of your container registry / ACR) +# - CONTAINER_NAME (name of the container image you would like to push up to your ACR) +# - RESOURCE_GROUP (where your cluster is deployed) +# - CLUSTER_NAME (name of your AKS cluster) +# - IMAGE_PULL_SECRET_NAME (name of the ImagePullSecret that will be created to pull your ACR image) +# +# 3. Choose the appropriate render engine for the bake step https://github.com/Azure/k8s-bake. The config below assumes Helm. +# Set your helmChart, overrideFiles, overrides, and helm-version to suit your configuration. +# - CHART_PATH (path to your helm chart) +# - CHART_OVERRIDE_PATH (path to your helm chart with override values) +# +# For more information on GitHub Actions for Azure, refer to https://github.com/Azure/Actions +# For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples +# For more options with the actions used below please refer to https://github.com/Azure/login + +name: testWorkflow + +on: + push: + branches: [testBranch] + workflow_dispatch: + +env: + ACR_RESOURCE_GROUP: testAcrRG + AZURE_CONTAINER_REGISTRY: testAcr + CONTAINER_NAME: testContainer + CLUSTER_RESOURCE_GROUP: testClusterRG + CLUSTER_NAME: testCluster + DOCKER_FILE: ./Dockerfile + BUILD_CONTEXT_PATH: test + CHART_PATH: ./charts + CHART_OVERRIDE_PATH: ./charts/production.yaml + CHART_OVERRIDES: replicas:2 + NAMESPACE: default + PRIVATE_CLUSTER: false + +jobs: + buildImage: + permissions: + contents: read + id-token: write + runs-on: ubuntu-latest + steps: + # Checks out the repository this file is in + - uses: actions/checkout@v3 + + # Logs in with your Azure credentials + - name: Azure login + uses: azure/login@v1.4.6 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + # Builds and pushes an image up to your Azure Container Registry + - name: Build and push image to ACR + run: | + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} -f ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} + deploy: + permissions: + actions: read + contents: read + id-token: write + runs-on: ubuntu-latest + needs: [buildImage] + steps: + # Checks out the repository this file is in + - uses: actions/checkout@v3 + + # Logs in with your Azure credentials + - name: Azure login + uses: azure/login@v1.4.6 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + # Use kubelogin to configure your kubeconfig for Azure auth + - name: Set up kubelogin for non-interactive login + uses: azure/use-kubelogin@v1 + with: + kubelogin-version: 'v0.0.25' + + # Retrieves your Azure Kubernetes Service cluster's kubeconfig file + - name: Get K8s context + uses: azure/aks-set-context@v3 + with: + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} + cluster-name: ${{ env.CLUSTER_NAME }} + admin: 'false' + use-kubelogin: 'true' + + # Runs Helm to create manifest files + - name: Bake deployment + uses: azure/k8s-bake@v2 + with: + renderEngine: "helm" + helmChart: ${{ env.CHART_PATH }} + overrideFiles: ${{ env.CHART_OVERRIDE_PATH }} + overrides: ${{ env.CHART_OVERRIDES }} + helm-version: "latest" + id: bake + + # Deploys application based on manifest files from previous step + - name: Deploy application + uses: Azure/k8s-deploy@v4 + with: + action: deploy + manifests: ${{ steps.bake.outputs.manifestsBundle }} + images: | + ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + namespace: ${{ env.NAMESPACE }} + private-cluster: ${{ env.PRIVATE_CLUSTER }} diff --git a/pkg/workflows/charts/production.yaml b/pkg/workflows/charts/production.yaml new file mode 100644 index 00000000..5e55a611 --- /dev/null +++ b/pkg/workflows/charts/production.yaml @@ -0,0 +1,8 @@ +image: + repository: testAcr.azurecr.io/testContainer + pullPolicy: Always + tag: latest +service: + annotations: {} + type: LoadBalancer + port: "80" diff --git a/pkg/workflows/workflows_test.go b/pkg/workflows/workflows_test.go index 4da6eae1..304ca6ca 100644 --- a/pkg/workflows/workflows_test.go +++ b/pkg/workflows/workflows_test.go @@ -25,8 +25,8 @@ func TestCreateWorkflows(t *testing.T) { dest := "." deployType := "helm" templatewriter := &writers.LocalFSWriter{} - flagValuesMap := map[string]string{"AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "RESOURCEGROUP": "testRG", "CLUSTERNAME": "testCluster", "BRANCHNAME": "testBranch", "BUILDCONTEXTPATH": "."} - flagValuesMapNoRoot := map[string]string{"AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "RESOURCEGROUP": "testRG", "CLUSTERNAME": "testCluster", "BRANCHNAME": "testBranch", "BUILDCONTEXTPATH": "test"} + flagValuesMap := map[string]string{"WORKFLOWNAME": "testWorkflow", "BRANCHNAME": "testBranch", "ACRRESOURCEGROUP": "testAcrRG", "AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "CLUSTERRESOURCEGROUP": "testClusterRG", "CLUSTERNAME": "testCluster", "DOCKERFILE": "./Dockerfile", "BUILDCONTEXTPATH": ".", "NAMESPACE": "default", "PRIVATECLUSTER": "false"} + flagValuesMapNoRoot := map[string]string{"WORKFLOWNAME": "testWorkflow", "BRANCHNAME": "testBranch", "ACRRESOURCEGROUP": "testAcrRG", "AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "CLUSTERRESOURCEGROUP": "testClusterRG", "CLUSTERNAME": "testCluster", "DOCKERFILE": "./Dockerfile", "BUILDCONTEXTPATH": "test", "NAMESPACE": "default", "PRIVATECLUSTER": "false"} tests := []struct { name string @@ -236,8 +236,8 @@ func TestPopulateConfigs(t *testing.T) { func TestCreateWorkflowFiles(t *testing.T) { templatewriter := &writers.LocalFSWriter{} - customInputs := map[string]string{"AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "RESOURCEGROUP": "testRG", "CLUSTERNAME": "testCluster", "BRANCHNAME": "testBranch", "CHARTPATH": "testPath", "CHARTOVERRIDEPATH": "testOverridePath", "BUILDCONTEXTPATH": "."} - customInputsNoRoot := map[string]string{"AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "RESOURCEGROUP": "testRG", "CLUSTERNAME": "testCluster", "BRANCHNAME": "testBranch", "CHARTPATH": "testPath", "CHARTOVERRIDEPATH": "testOverridePath", "BUILDCONTEXTPATH": "test"} + customInputs := map[string]string{"WORKFLOWNAME": "testWorkflow", "BRANCHNAME": "testBranch", "ACRRESOURCEGROUP": "testAcrRG", "AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "CLUSTERRESOURCEGROUP": "testClusterRG", "CLUSTERNAME": "testCluster", "DOCKERFILE": "./Dockerfile", "BUILDCONTEXTPATH": ".", "CHARTPATH": "testPath", "CHARTOVERRIDEPATH": "testOverridePath", "CHARTOVERRIDES": "replicas:2", "NAMESPACE": "default", "PRIVATECLUSTER": "false"} + customInputsNoRoot := map[string]string{"WORKFLOWNAME": "testWorkflow", "BRANCHNAME": "testBranch", "ACRRESOURCEGROUP": "testAcrRG", "AZURECONTAINERREGISTRY": "testAcr", "CONTAINERNAME": "testContainer", "CLUSTERRESOURCEGROUP": "testClusterRG", "CLUSTERNAME": "testCluster", "DOCKERFILE": "./Dockerfile", "BUILDCONTEXTPATH": ".", "CHARTPATH": "testPath", "CHARTOVERRIDEPATH": "testOverridePath", "CHARTOVERRIDES": "replicas:2", "NAMESPACE": "default", "PRIVATECLUSTER": "false"} badInputs := map[string]string{} workflowTemplate, err := createMockWorkflowTemplatesFS() From be850bd4e6bea976449788ceec9f10909e8259de Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 10:36:49 -0400 Subject: [PATCH 34/44] fixing cli calls --- .github/workflows/integration-linux.yml | 2 +- pkg/workflows/workflows_test.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-linux.yml b/.github/workflows/integration-linux.yml index 86c0952c..12b29d11 100644 --- a/.github/workflows/integration-linux.yml +++ b/.github/workflows/integration-linux.yml @@ -139,7 +139,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . --n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf diff --git a/pkg/workflows/workflows_test.go b/pkg/workflows/workflows_test.go index 304ca6ca..621d55c9 100644 --- a/pkg/workflows/workflows_test.go +++ b/pkg/workflows/workflows_test.go @@ -63,7 +63,8 @@ func TestCreateWorkflows(t *testing.T) { os.Remove(".overlays") os.Remove(".github") }, - }, { + }, + { name: "manifests", deployType: "manifests", flagValues: flagValuesMap, From e186f263052cf2466168d4376da42a0f95504130 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 10:42:50 -0400 Subject: [PATCH 35/44] typo --- .github/workflows/integration-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-linux.yml b/.github/workflows/integration-linux.yml index 12b29d11..42425223 100644 --- a/.github/workflows/integration-linux.yml +++ b/.github/workflows/integration-linux.yml @@ -139,7 +139,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . --n default --private-cluster false + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf From b96f437939c07f80cdb9ffd54c27faa2ee18923b Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 10:54:47 -0400 Subject: [PATCH 36/44] updated flag key --- cmd/generate-workflow.go | 4 ++-- pkg/workflows/workflowconfig.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/generate-workflow.go b/cmd/generate-workflow.go index 0af0de77..db90c9a3 100644 --- a/cmd/generate-workflow.go +++ b/cmd/generate-workflow.go @@ -52,6 +52,8 @@ with draft on AKS. This command assumes the 'setup-gh' command has been run prop } f := cmd.Flags() + f.StringVarP(&gwCmd.dest, "destination", "d", currentDirDefaultFlagValue, "specify the path to the project directory") + f.StringVar(&gwCmd.deployType, "deploy-type", emptyDefaultFlagValue, "specify the type of deployment") f.StringVarP(&gwCmd.workflowConfig.WorkflowName, "workflow", "w", emptyDefaultFlagValue, "specify the Github workflow name") f.StringVarP(&gwCmd.workflowConfig.BranchName, "branch", "b", emptyDefaultFlagValue, "specify the Github branch to automatically deploy from") f.StringVar(&gwCmd.workflowConfig.AcrResourceGroup, "acr-resource-group", emptyDefaultFlagValue, "specify the Azure container registry resource group") @@ -63,8 +65,6 @@ with draft on AKS. This command assumes the 'setup-gh' command has been run prop f.StringVarP(&gwCmd.workflowConfig.BuildContextPath, "build-context-path", "x", emptyDefaultFlagValue, "specify the docker build context path") f.StringVarP(&gwCmd.workflowConfig.Namespace, "namespace", "n", emptyDefaultFlagValue, "specify the Kubernetes namespace") f.StringVar(&gwCmd.workflowConfig.PrivateCluster, "private-cluster", emptyDefaultFlagValue, "specify if the AKS cluster is private") - f.StringVarP(&gwCmd.dest, "destination", "d", currentDirDefaultFlagValue, "specify the path to the project directory") - f.StringVar(&gwCmd.deployType, "deploy-type", emptyDefaultFlagValue, "specify the type of deployment") f.StringArrayVarP(&gwCmd.flagVariables, "variable", "", []string{}, "pass additional variables") gwCmd.templateWriter = &writers.LocalFSWriter{} return cmd diff --git a/pkg/workflows/workflowconfig.go b/pkg/workflows/workflowconfig.go index ea884fde..17e53ddf 100644 --- a/pkg/workflows/workflowconfig.go +++ b/pkg/workflows/workflowconfig.go @@ -37,7 +37,7 @@ func (config *WorkflowConfig) SetFlagValuesToMap() map[string]string { } if config.ClusterResourceGroup != "" { - flagValuesMap["RESOURCEGROUP"] = config.ClusterResourceGroup + flagValuesMap["CLUSTERRESOURCEGROUP"] = config.ClusterResourceGroup } if config.ClusterName != "" { From f32b9d46c69d148765503e27c65f52060f38f271 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 12:51:12 -0400 Subject: [PATCH 37/44] Updated integration tests --- .github/workflows/integration-linux.yml | 71 ++++++++++++------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/.github/workflows/integration-linux.yml b/.github/workflows/integration-linux.yml index 42425223..3c882510 100644 --- a/.github/workflows/integration-linux.yml +++ b/.github/workflows/integration-linux.yml @@ -273,7 +273,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -398,7 +398,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -577,7 +577,7 @@ jobs: curl -m 3 $SERVICEIP:8080 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -711,7 +711,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:8080 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -836,7 +836,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:8080 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1015,7 +1015,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -1149,7 +1149,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1274,7 +1274,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1453,7 +1453,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -1587,7 +1587,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1712,8 +1712,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . - # Validate generated workflow yaml + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 with: @@ -1891,7 +1890,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -2025,7 +2024,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2150,7 +2149,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2329,7 +2328,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -2463,7 +2462,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2588,7 +2587,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2767,7 +2766,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -2901,7 +2900,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3026,7 +3025,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3205,7 +3204,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -3339,7 +3338,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3464,7 +3463,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3643,7 +3642,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -3777,7 +3776,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3902,7 +3901,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4081,7 +4080,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -4215,7 +4214,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4340,7 +4339,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4519,7 +4518,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -4653,7 +4652,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4778,7 +4777,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4957,7 +4956,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -5091,7 +5090,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -5216,7 +5215,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 From bd4c774d15310454fd4c51f65a5b05db7a88d61d Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 13:07:07 -0400 Subject: [PATCH 38/44] got rid of test files --- .../azure-kubernetes-service-helm.yml | 132 ------------------ pkg/workflows/charts/production.yaml | 8 -- 2 files changed, 140 deletions(-) delete mode 100644 pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml delete mode 100644 pkg/workflows/charts/production.yaml diff --git a/pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml b/pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml deleted file mode 100644 index 65624bde..00000000 --- a/pkg/workflows/.github/workflows/azure-kubernetes-service-helm.yml +++ /dev/null @@ -1,132 +0,0 @@ -# This workflow will build and push an application to a Azure Kubernetes Service (AKS) cluster when you push your code -# -# This workflow assumes you have already created the target AKS cluster and have created an Azure Container Registry (ACR) -# The ACR should be attached to the AKS cluster -# For instructions see: -# - https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal -# - https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal -# - https://learn.microsoft.com/en-us/azure/aks/cluster-container-registry-integration?tabs=azure-cli#configure-acr-integration-for-existing-aks-clusters -# - https://github.com/Azure/aks-create-action -# -# To configure this workflow: -# -# 1. Set the following secrets in your repository (instructions for getting these -# https://docs.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-cli%2Clinux)): -# - AZURE_CLIENT_ID -# - AZURE_TENANT_ID -# - AZURE_SUBSCRIPTION_ID -# -# 2. Set the following environment variables (or replace the values below): -# - AZURE_CONTAINER_REGISTRY (name of your container registry / ACR) -# - CONTAINER_NAME (name of the container image you would like to push up to your ACR) -# - RESOURCE_GROUP (where your cluster is deployed) -# - CLUSTER_NAME (name of your AKS cluster) -# - IMAGE_PULL_SECRET_NAME (name of the ImagePullSecret that will be created to pull your ACR image) -# -# 3. Choose the appropriate render engine for the bake step https://github.com/Azure/k8s-bake. The config below assumes Helm. -# Set your helmChart, overrideFiles, overrides, and helm-version to suit your configuration. -# - CHART_PATH (path to your helm chart) -# - CHART_OVERRIDE_PATH (path to your helm chart with override values) -# -# For more information on GitHub Actions for Azure, refer to https://github.com/Azure/Actions -# For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples -# For more options with the actions used below please refer to https://github.com/Azure/login - -name: testWorkflow - -on: - push: - branches: [testBranch] - workflow_dispatch: - -env: - ACR_RESOURCE_GROUP: testAcrRG - AZURE_CONTAINER_REGISTRY: testAcr - CONTAINER_NAME: testContainer - CLUSTER_RESOURCE_GROUP: testClusterRG - CLUSTER_NAME: testCluster - DOCKER_FILE: ./Dockerfile - BUILD_CONTEXT_PATH: test - CHART_PATH: ./charts - CHART_OVERRIDE_PATH: ./charts/production.yaml - CHART_OVERRIDES: replicas:2 - NAMESPACE: default - PRIVATE_CLUSTER: false - -jobs: - buildImage: - permissions: - contents: read - id-token: write - runs-on: ubuntu-latest - steps: - # Checks out the repository this file is in - - uses: actions/checkout@v3 - - # Logs in with your Azure credentials - - name: Azure login - uses: azure/login@v1.4.6 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - # Builds and pushes an image up to your Azure Container Registry - - name: Build and push image to ACR - run: | - az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} -f ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} - deploy: - permissions: - actions: read - contents: read - id-token: write - runs-on: ubuntu-latest - needs: [buildImage] - steps: - # Checks out the repository this file is in - - uses: actions/checkout@v3 - - # Logs in with your Azure credentials - - name: Azure login - uses: azure/login@v1.4.6 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - # Use kubelogin to configure your kubeconfig for Azure auth - - name: Set up kubelogin for non-interactive login - uses: azure/use-kubelogin@v1 - with: - kubelogin-version: 'v0.0.25' - - # Retrieves your Azure Kubernetes Service cluster's kubeconfig file - - name: Get K8s context - uses: azure/aks-set-context@v3 - with: - resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} - cluster-name: ${{ env.CLUSTER_NAME }} - admin: 'false' - use-kubelogin: 'true' - - # Runs Helm to create manifest files - - name: Bake deployment - uses: azure/k8s-bake@v2 - with: - renderEngine: "helm" - helmChart: ${{ env.CHART_PATH }} - overrideFiles: ${{ env.CHART_OVERRIDE_PATH }} - overrides: ${{ env.CHART_OVERRIDES }} - helm-version: "latest" - id: bake - - # Deploys application based on manifest files from previous step - - name: Deploy application - uses: Azure/k8s-deploy@v4 - with: - action: deploy - manifests: ${{ steps.bake.outputs.manifestsBundle }} - images: | - ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} - namespace: ${{ env.NAMESPACE }} - private-cluster: ${{ env.PRIVATE_CLUSTER }} diff --git a/pkg/workflows/charts/production.yaml b/pkg/workflows/charts/production.yaml deleted file mode 100644 index 5e55a611..00000000 --- a/pkg/workflows/charts/production.yaml +++ /dev/null @@ -1,8 +0,0 @@ -image: - repository: testAcr.azurecr.io/testContainer - pullPolicy: Always - tag: latest -service: - annotations: {} - type: LoadBalancer - port: "80" From 4c19f472e3ff0ff2a3ec4b4dc2b363cf44ff0884 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 13:31:26 -0400 Subject: [PATCH 39/44] got rid of second branch flag arg --- .github/workflows/integration-linux.yml | 72 ++++++++++++------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/integration-linux.yml b/.github/workflows/integration-linux.yml index 3c882510..f262a193 100644 --- a/.github/workflows/integration-linux.yml +++ b/.github/workflows/integration-linux.yml @@ -139,7 +139,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -273,7 +273,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -398,7 +398,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -577,7 +577,7 @@ jobs: curl -m 3 $SERVICEIP:8080 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -711,7 +711,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:8080 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -836,7 +836,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:8080 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1015,7 +1015,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -1149,7 +1149,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1274,7 +1274,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1453,7 +1453,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -1587,7 +1587,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -1712,7 +1712,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 with: @@ -1890,7 +1890,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -2024,7 +2024,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2149,7 +2149,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2328,7 +2328,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -2462,7 +2462,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2587,7 +2587,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -2766,7 +2766,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -2900,7 +2900,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3025,7 +3025,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3204,7 +3204,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -3338,7 +3338,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3463,7 +3463,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3642,7 +3642,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -3776,7 +3776,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -3901,7 +3901,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4080,7 +4080,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -4214,7 +4214,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4339,7 +4339,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4518,7 +4518,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -4652,7 +4652,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4777,7 +4777,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -4956,7 +4956,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -5090,7 +5090,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -5215,7 +5215,7 @@ jobs: echo 'Curling service IP' curl -m 3 $SERVICEIP:80 kill $tunnelPID - - run: ./draft -b main -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b someBranch --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 From 74e87839868f3b7ba324dc8418114ce662157dfe Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 14:00:16 -0400 Subject: [PATCH 40/44] updated gen_integration.sh --- .github/workflows/integration-linux.yml | 1 + test/gen_integration.sh | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-linux.yml b/.github/workflows/integration-linux.yml index f262a193..8d092931 100644 --- a/.github/workflows/integration-linux.yml +++ b/.github/workflows/integration-linux.yml @@ -1713,6 +1713,7 @@ jobs: curl -m 3 $SERVICEIP:80 kill $tunnelPID - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false + # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 with: diff --git a/test/gen_integration.sh b/test/gen_integration.sh index 722f5eb4..24ffb4f8 100755 --- a/test/gen_integration.sh +++ b/test/gen_integration.sh @@ -305,7 +305,7 @@ languageVariables: curl -m 3 \$SERVICEIP:$serviceport kill \$tunnelPID - run: | - ./draft -b main -v generate-workflow -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type helm --build-context-path . + ./draft -v generate-workflow -d ./langtest/ --deploy-type helm -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false pwd # Validate generated workflow yaml - name: Install action-validator with asdf @@ -455,7 +455,7 @@ languageVariables: echo 'Curling service IP' curl -m 3 \$SERVICEIP:$serviceport kill \$tunnelPID - - run: ./draft -v generate-workflow -b main -d ./langtest/ -c someAksCluster -r someRegistry -g someResourceGroup --container-name someContainer --deploy-type kustomize --build-context-path . + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type kustomize -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 @@ -596,7 +596,7 @@ languageVariables: echo 'Curling service IP' curl -m 3 \$SERVICEIP:$serviceport kill \$tunnelPID - - run: ./draft -v generate-workflow -d ./langtest/ -b main -c someAksCluster -r localhost -g someResourceGroup --container-name testapp --deploy-type manifests --build-context-path . + - run: ./draft -v generate-workflow -d ./langtest/ --deploy-type manifests -w someWorkflow -b main --acr-resource-group someAcrResourceGroup -r someRegistry --container-name someContainer -g someClusterResourceGroup -c someAksCluster --dockerfile ./Dockerfile --build-context-path . -n default --private-cluster false # Validate generated workflow yaml - name: Install action-validator with asdf uses: asdf-vm/actions/install@v1 From 11ffd24006e8400d7dc568767c1e4fb21312b0ba Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 16:48:25 -0400 Subject: [PATCH 41/44] added test for ApplyDefaultVariables --- pkg/config/draftconfig.go | 9 +- pkg/config/draftconfig_test.go | 188 ++++++++++++++++++++++++ template/workflows/helm/draft.yaml | 2 +- template/workflows/kustomize/draft.yaml | 2 +- template/workflows/manifests/draft.yaml | 2 +- 5 files changed, 196 insertions(+), 7 deletions(-) create mode 100644 pkg/config/draftconfig_test.go diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index 99840647..f85b1f95 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -76,7 +76,7 @@ func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) erro // handle where variable is not set or is set to an empty string from cli handling if customInputs[variable.Name] == "" { if variable.Default.ReferenceVar != "" { - defaultVal, err := recurseReferenceVars(d.Variables, variable, customInputs, varIdxMap, variable, true) + defaultVal, err := recurseReferenceVars(d.Variables, d.Variables[varIdxMap[variable.Default.ReferenceVar]], customInputs, varIdxMap, d.Variables[varIdxMap[variable.Default.ReferenceVar]], true) if err != nil { return fmt.Errorf("apply default variables: %w", err) } @@ -98,13 +98,14 @@ func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) erro return nil } +// recurseReferenceVars recursively checks each variable's ReferenceVar if it doesn't have a custom input. If there's no more ReferenceVars, it will return the default value of the last ReferenceVar. func recurseReferenceVars(variables []BuilderVar, variable BuilderVar, customInputs map[string]string, varIdxMap map[string]int, variableCheck BuilderVar, isFirst bool) (string, error) { if !isFirst && variable.Name == variableCheck.Name { - return "", errors.New("circular reference detected") + return "", errors.New("cyclical reference detected") } - if customInputs[variable.Default.ReferenceVar] != "" { - return customInputs[variable.Default.ReferenceVar], nil + if customInputs[variable.Name] != "" { + return customInputs[variable.Name], nil } else if variable.Default.ReferenceVar != "" { return recurseReferenceVars(variables, variables[varIdxMap[variable.Default.ReferenceVar]], customInputs, varIdxMap, variableCheck, false) } diff --git a/pkg/config/draftconfig_test.go b/pkg/config/draftconfig_test.go new file mode 100644 index 00000000..7956a812 --- /dev/null +++ b/pkg/config/draftconfig_test.go @@ -0,0 +1,188 @@ +package config + +import ( + "testing" +) + +func TestApplyDefaultVariables(t *testing.T) { + tests := []struct { + testName string + draftConfig DraftConfig + customInputs map[string]string + want map[string]string + wantErr bool + }{ + { + testName: "keepAllCustomInputs", + draftConfig: DraftConfig{ + Variables: []BuilderVar{ + { + Name: "var1", + Default: BuilderVarDefault{ + Value: "default-value-1", + }, + }, + { + Name: "var2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + customInputs: map[string]string{ + "var1": "custom-value-1", + "var2": "custom-value-2", + }, + want: map[string]string{ + "var1": "custom-value-1", + "var2": "custom-value-2", + }, + }, + { + testName: "applyDefaultToEmptyCustomInputs", + draftConfig: DraftConfig{ + Variables: []BuilderVar{ + { + Name: "var1", + Default: BuilderVarDefault{ + Value: "default-value-1", + }, + }, + { + Name: "var2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + customInputs: map[string]string{}, + want: map[string]string{ + "var1": "default-value-1", + "var2": "default-value-2", + }, + }, + { + testName: "applyDefaultToPartialCustomInputs", + draftConfig: DraftConfig{ + Variables: []BuilderVar{ + { + Name: "var1", + Default: BuilderVarDefault{ + Value: "default-value-1", + }, + }, + { + Name: "var2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + customInputs: map[string]string{ + "var1": "custom-value-1", + }, + want: map[string]string{ + "var1": "custom-value-1", + "var2": "default-value-2", + }, + }, + { + testName: "getDefaultFromReferenceVarCustomInputs", + draftConfig: DraftConfig{ + Variables: []BuilderVar{ + { + Name: "var1", + Default: BuilderVarDefault{ + ReferenceVar: "var2", + Value: "not-this-value", + }, + }, + { + Name: "var2", + Default: BuilderVarDefault{ + Value: "not-this-value", + }, + }, + }, + }, + customInputs: map[string]string{ + "var2": "this-value", + }, + want: map[string]string{ + "var1": "this-value", + "var2": "this-value", + }, + }, + { + testName: "getDefaultFromReferenceVar", + draftConfig: DraftConfig{ + Variables: []BuilderVar{ + { + Name: "var1", + Default: BuilderVarDefault{ + ReferenceVar: "var2", + Value: "not-this-value", + }, + }, + { + Name: "var2", + Default: BuilderVarDefault{ + ReferenceVar: "var3", + Value: "not-this-value", + }, + }, + { + Name: "var3", + Default: BuilderVarDefault{ + Value: "default-value-3", + }, + }, + }, + }, + customInputs: map[string]string{}, + want: map[string]string{ + "var1": "default-value-3", + "var2": "default-value-3", + "var3": "default-value-3", + }, + }, + { + testName: "cyclicalReferenceVarsDetected", + draftConfig: DraftConfig{ + Variables: []BuilderVar{ + { + Name: "var1", + Default: BuilderVarDefault{ + ReferenceVar: "var2", + }, + }, + { + Name: "var2", + Default: BuilderVarDefault{ + ReferenceVar: "var1", + }, + }, + }, + }, + customInputs: map[string]string{}, + want: map[string]string{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + if err := tt.draftConfig.ApplyDefaultVariables(tt.customInputs); (err != nil) != tt.wantErr { + t.Error(err) + } else { + for k, v := range tt.want { + if tt.customInputs[k] != v { + t.Errorf("got: %s, want: %s", tt.customInputs[k], v) + } + } + } + }) + } +} diff --git a/template/workflows/helm/draft.yaml b/template/workflows/helm/draft.yaml index 674a0d27..26c99b89 100644 --- a/template/workflows/helm/draft.yaml +++ b/template/workflows/helm/draft.yaml @@ -45,6 +45,6 @@ variables: - name: "PRIVATECLUSTER" default: value: "false" - description: "set to true if the AKS cluster is private" + description: "true if the AKS cluster is private" type: "bool" \ No newline at end of file diff --git a/template/workflows/kustomize/draft.yaml b/template/workflows/kustomize/draft.yaml index 39ce6943..b0c8bc93 100644 --- a/template/workflows/kustomize/draft.yaml +++ b/template/workflows/kustomize/draft.yaml @@ -35,5 +35,5 @@ variables: - name: "PRIVATECLUSTER" default: value: "false" - description: "set to true if the AKS cluster is private" + description: "true if the AKS cluster is private" type: "bool" diff --git a/template/workflows/manifests/draft.yaml b/template/workflows/manifests/draft.yaml index 00e8a29b..e1edbdad 100644 --- a/template/workflows/manifests/draft.yaml +++ b/template/workflows/manifests/draft.yaml @@ -35,5 +35,5 @@ variables: - name: "PRIVATECLUSTER" default: value: "false" - description: "set to true if the AKS cluster is private" + description: "true if the AKS cluster is private" type: "bool" From 23d3c2e3a43fdb9e7bf3a1f0d54dd3ba1a6e4515 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 16:51:58 -0400 Subject: [PATCH 42/44] wip --- pkg/config/draftconfig_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pkg/config/draftconfig_test.go b/pkg/config/draftconfig_test.go index 7956a812..833123b0 100644 --- a/pkg/config/draftconfig_test.go +++ b/pkg/config/draftconfig_test.go @@ -89,6 +89,22 @@ func TestApplyDefaultVariables(t *testing.T) { "var2": "default-value-2", }, }, + { + testName: "variablesHaveNoInputOrDefault", + draftConfig: DraftConfig{ + Variables: []BuilderVar{ + { + Name: "var1", + }, + { + Name: "var2", + }, + }, + }, + customInputs: map[string]string{}, + want: map[string]string{}, + wantErr: true, + }, { testName: "getDefaultFromReferenceVarCustomInputs", draftConfig: DraftConfig{ From e201a5ba4e9ddaa7bdf8be46f73250627c1a1823 Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Tue, 25 Jun 2024 19:45:44 -0400 Subject: [PATCH 43/44] removed GenerateWorkflowBytes --- cmd/generate-workflow.go | 2 +- pkg/workflows/workflowconfig.go | 6 +++--- pkg/workflows/workflows.go | 34 --------------------------------- 3 files changed, 4 insertions(+), 38 deletions(-) diff --git a/cmd/generate-workflow.go b/cmd/generate-workflow.go index db90c9a3..0e73a5f2 100644 --- a/cmd/generate-workflow.go +++ b/cmd/generate-workflow.go @@ -57,7 +57,7 @@ with draft on AKS. This command assumes the 'setup-gh' command has been run prop f.StringVarP(&gwCmd.workflowConfig.WorkflowName, "workflow", "w", emptyDefaultFlagValue, "specify the Github workflow name") f.StringVarP(&gwCmd.workflowConfig.BranchName, "branch", "b", emptyDefaultFlagValue, "specify the Github branch to automatically deploy from") f.StringVar(&gwCmd.workflowConfig.AcrResourceGroup, "acr-resource-group", emptyDefaultFlagValue, "specify the Azure container registry resource group") - f.StringVarP(&gwCmd.workflowConfig.Acr, "registry-name", "r", emptyDefaultFlagValue, "specify the Azure container registry name") + f.StringVarP(&gwCmd.workflowConfig.AcrName, "registry-name", "r", emptyDefaultFlagValue, "specify the Azure container registry name") f.StringVar(&gwCmd.workflowConfig.ContainerName, "container-name", emptyDefaultFlagValue, "specify the container image name") f.StringVarP(&gwCmd.workflowConfig.ClusterResourceGroup, "cluster-resource-group", "g", emptyDefaultFlagValue, "specify the Azure resource group of your AKS cluster") f.StringVarP(&gwCmd.workflowConfig.ClusterName, "cluster-name", "c", emptyDefaultFlagValue, "specify the AKS cluster name") diff --git a/pkg/workflows/workflowconfig.go b/pkg/workflows/workflowconfig.go index 17e53ddf..5aace52e 100644 --- a/pkg/workflows/workflowconfig.go +++ b/pkg/workflows/workflowconfig.go @@ -4,7 +4,7 @@ type WorkflowConfig struct { WorkflowName string BranchName string AcrResourceGroup string - Acr string + AcrName string ContainerName string ClusterResourceGroup string ClusterName string @@ -28,8 +28,8 @@ func (config *WorkflowConfig) SetFlagValuesToMap() map[string]string { flagValuesMap["ACRRESOURCEGROUP"] = config.AcrResourceGroup } - if config.Acr != "" { - flagValuesMap["AZURECONTAINERREGISTRY"] = config.Acr + if config.AcrName != "" { + flagValuesMap["AZURECONTAINERREGISTRY"] = config.AcrName } if config.ContainerName != "" { diff --git a/pkg/workflows/workflows.go b/pkg/workflows/workflows.go index 5d2b5df5..1bc4b851 100644 --- a/pkg/workflows/workflows.go +++ b/pkg/workflows/workflows.go @@ -20,7 +20,6 @@ import ( "github.com/Azure/draft/pkg/embedutils" "github.com/Azure/draft/pkg/osutil" "github.com/Azure/draft/pkg/templatewriter" - "github.com/Azure/draft/template" ) const ( @@ -188,36 +187,3 @@ func (w *Workflows) CreateWorkflowFiles(deployType string, customInputs map[stri return nil } - -func GenerateWorkflowBytes(draftConfig *config.DraftConfig, deployType string) ([]byte, error) { - envArgs, err := draftConfig.VariableMap() - if err != nil { - return nil, fmt.Errorf("generate workflow bytes: %w", err) - } - - if err = draftConfig.ApplyDefaultVariables(envArgs); err != nil { - return nil, fmt.Errorf("apply default variables: %w", err) - } - - var srcPath string - - switch deployType { - case "helm": - srcPath = "workflow/helm/.github/workflows/azure-kubernetes-service-helm.yml" - case "manifests": - srcPath = "workflow/manifests/.github/workflows/azure-kubernetes-service.yml" - default: - return nil, errors.New("unsupported deploy type") - } - - workflowBytes, err := osutil.ReplaceTemplateVariables(template.Workflows, srcPath, envArgs) - if err != nil { - return nil, fmt.Errorf("replace template variables: %w", err) - } - - if err = osutil.CheckAllVariablesSubstituted(string(workflowBytes)); err != nil { - return nil, fmt.Errorf("check all variables substituted: %w", err) - } - - return workflowBytes, nil -} From b9054e6128842bb2238b5110089c58aa17b77a1d Mon Sep 17 00:00:00 2001 From: t-mferrari Date: Wed, 26 Jun 2024 15:51:25 -0400 Subject: [PATCH 44/44] made tests more thorough --- pkg/config/draftconfig.go | 12 ++++++------ pkg/config/draftconfig_test.go | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index f85b1f95..6d6a6eb2 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -89,7 +89,7 @@ func (d *DraftConfig) ApplyDefaultVariables(customInputs map[string]string) erro log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Default.Value) customInputs[variable.Name] = variable.Default.Value } else { - return errors.New("variable " + variable.Name + " has no default value") + return fmt.Errorf("variable %s has no default value", variable.Name) } } } @@ -123,11 +123,6 @@ func VariableIdxMap(variables []BuilderVar) map[string]int { return varIdxMap } -// TemplateVariableRecorder is an interface for recording variables that are used read using draft configs -type TemplateVariableRecorder interface { - Record(key, value string) -} - func (d *DraftConfig) VariableMap() (map[string]string, error) { envArgs := make(map[string]string) @@ -152,3 +147,8 @@ func (d *DraftConfig) VariableIdxMap() map[string]int { return varIdxMap } + +// TemplateVariableRecorder is an interface for recording variables that are used read using draft configs +type TemplateVariableRecorder interface { + Record(key, value string) +} diff --git a/pkg/config/draftconfig_test.go b/pkg/config/draftconfig_test.go index 833123b0..20bd1f2a 100644 --- a/pkg/config/draftconfig_test.go +++ b/pkg/config/draftconfig_test.go @@ -10,7 +10,7 @@ func TestApplyDefaultVariables(t *testing.T) { draftConfig DraftConfig customInputs map[string]string want map[string]string - wantErr bool + wantErrMsg string }{ { testName: "keepAllCustomInputs", @@ -103,7 +103,7 @@ func TestApplyDefaultVariables(t *testing.T) { }, customInputs: map[string]string{}, want: map[string]string{}, - wantErr: true, + wantErrMsg: "variable var1 has no default value", }, { testName: "getDefaultFromReferenceVarCustomInputs", @@ -185,12 +185,12 @@ func TestApplyDefaultVariables(t *testing.T) { }, customInputs: map[string]string{}, want: map[string]string{}, - wantErr: true, + wantErrMsg: "apply default variables: cyclical reference detected", }, } for _, tt := range tests { t.Run(tt.testName, func(t *testing.T) { - if err := tt.draftConfig.ApplyDefaultVariables(tt.customInputs); (err != nil) != tt.wantErr { + if err := tt.draftConfig.ApplyDefaultVariables(tt.customInputs); err != nil && err.Error() != tt.wantErrMsg { t.Error(err) } else { for k, v := range tt.want {