From 135afd0948e5bd3874a9b7cf6fe41ed13dee1361 Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:54:49 -0700 Subject: [PATCH 1/2] signing the commits --- .github/pull_request_template.md | 16 +- .github/workflows/unit-tests.yml | 7 +- cmd/create.go | 86 +++-- cmd/create_test.go | 26 +- cmd/info.go | 26 +- cmd/setup-gh.go | 8 + example/deployment.go | 106 ++---- example/deployment_test.go | 154 -------- example/dockerfile.go | 57 ++- example/dockerfile_test.go | 112 ------ go.mod | 26 +- go.sum | 231 +---------- pkg/azurePipelines/azurePipelines.go | 133 ------- pkg/azurePipelines/azurePipelines_test.go | 174 --------- pkg/config/draftconfig.go | 117 ++++++ pkg/config/draftconfig_template_test.go | 99 ++++- pkg/config/draftconfig_test.go | 168 ++++++++ pkg/deployments/deployments.go | 111 ------ pkg/deployments/deployments_test.go | 252 ------------ pkg/filematches/filematches.go | 30 +- .../deployments/{ => helm}/charts/.helmignore | 0 .../deployments/{ => helm}/charts/Chart.yaml | 0 .../{ => helm}/charts/production.yaml | 0 .../{ => helm}/charts/templates/_helpers.tpl | 0 .../charts/templates/deployment.yaml | 0 .../{ => helm}/charts/templates/service.yaml | 0 .../deployments/{ => helm}/charts/values.yaml | 0 .../kustomize/base/deployment.yaml | 24 ++ .../kustomize/base/kustomization.yaml | 5 + .../deployments/kustomize/base/namespace.yaml | 6 + .../deployments/kustomize/base/service.yaml | 15 + .../overlays/production/deployment.yaml | 17 + .../overlays/production/kustomization.yaml | 7 + .../overlays/production/service.yaml | 9 + .../manifest/manifests/deployment.yaml | 24 ++ .../manifest/manifests/service.yaml | 15 + .../dockerfiles/clojure/.dockerignore | 5 + pkg/fixtures/dockerfiles/clojure/Dockerfile | 13 + pkg/fixtures/dockerfiles/csharp/.dockerignore | 4 + pkg/fixtures/dockerfiles/csharp/Dockerfile | 21 + pkg/fixtures/dockerfiles/erlang/.dockerignore | 3 + pkg/fixtures/dockerfiles/erlang/Dockerfile | 40 ++ pkg/fixtures/dockerfiles/go/.dockerignore | 2 + pkg/fixtures/dockerfiles/go/Dockerfile | 12 + .../dockerfiles/gomodule/.dockerignore | 2 + pkg/fixtures/dockerfiles/gomodule/Dockerfile | 16 + pkg/fixtures/dockerfiles/gradle/.dockerignore | 2 + pkg/fixtures/dockerfiles/gradle/Dockerfile | 13 + .../dockerfiles/gradlew/.dockerignore | 2 + pkg/fixtures/dockerfiles/gradlew/Dockerfile | 17 + pkg/fixtures/dockerfiles/java/.dockerignore | 5 + pkg/fixtures/dockerfiles/java/Dockerfile | 12 + .../dockerfiles/javascript/.dockerignore | 2 + .../dockerfiles/javascript/Dockerfile | 11 + pkg/fixtures/dockerfiles/php/.dockerignore | 2 + pkg/fixtures/dockerfiles/php/Dockerfile | 11 + pkg/fixtures/dockerfiles/python/.dockerignore | 2 + pkg/fixtures/dockerfiles/python/Dockerfile | 12 + pkg/fixtures/dockerfiles/ruby/.dockerignore | 3 + pkg/fixtures/dockerfiles/ruby/Dockerfile | 12 + pkg/fixtures/dockerfiles/rust/.dockerignore | 3 + pkg/fixtures/dockerfiles/rust/Dockerfile | 10 + pkg/fixtures/dockerfiles/swift/.dockerignore | 2 + pkg/fixtures/dockerfiles/swift/Dockerfile | 11 + pkg/fixtures/validatetemplate.go | 11 +- .../.pipelines/azure-kubernetes-service.yaml | 68 ++++ .../.pipelines/azure-kubernetes-service.yaml | 60 +++ pkg/handlers/template.go | 198 ++++++++++ pkg/handlers/template_test.go | 360 ++++++++++++++++++ pkg/handlers/template_utils.go | 115 ++++++ pkg/handlers/template_utils_test.go | 20 + .../variableextractors}/defaults/gradle.go | 0 .../defaults/gradle_test.go | 0 .../variableextractors}/defaults/python.go | 0 .../defaults/python_test.go | 0 .../defaults/testdata/sample.gradle | 0 pkg/languages/languages.go | 146 ------- pkg/languages/languages_test.go | 32 -- pkg/providers/az-client.go | 19 +- pkg/providers/azure.go | 35 +- .../writers/filemapwriter_test.go | 16 +- pkg/workflows/manifests/deployment.yaml | 22 ++ .../overlays/production/deployment.yaml | 12 + template/README.md | 43 +++ template/azurePipelines.go | 8 - .../.pipelines/azure-kubernetes-service.yaml | 20 +- template/azurePipelines/kustomize/draft.yaml | 12 + .../.pipelines/azure-kubernetes-service.yaml | 20 +- template/azurePipelines/manifests/draft.yaml | 12 + template/deployments.go | 8 - template/deployments/helm/charts/Chart.yaml | 2 +- .../deployments/helm/charts/production.yaml | 4 +- .../helm/charts/templates/_helpers.tpl | 16 +- .../helm/charts/templates/deployment.yaml | 8 +- .../helm/charts/templates/service.yaml | 6 +- template/deployments/helm/charts/values.yaml | 15 +- template/deployments/helm/draft.yaml | 9 + .../kustomize/base/deployment.yaml | 18 +- .../deployments/kustomize/base/namespace.yaml | 4 +- .../deployments/kustomize/base/service.yaml | 12 +- template/deployments/kustomize/draft.yaml | 9 + .../overlays/production/deployment.yaml | 14 +- .../overlays/production/kustomization.yaml | 2 +- .../overlays/production/service.yaml | 8 +- template/deployments/manifests/draft.yaml | 11 +- .../manifests/manifests/deployment.yaml | 18 +- .../manifests/manifests/service.yaml | 12 +- template/dockerfiles.go | 8 - template/dockerfiles/clojure/.dockerignore | 2 +- template/dockerfiles/clojure/Dockerfile | 6 +- template/dockerfiles/clojure/draft.yaml | 12 + template/dockerfiles/csharp/.dockerignore | 2 +- template/dockerfiles/csharp/Dockerfile | 10 +- template/dockerfiles/csharp/draft.yaml | 12 + template/dockerfiles/erlang/.dockerignore | 1 + template/dockerfiles/erlang/Dockerfile | 8 +- template/dockerfiles/erlang/draft.yaml | 13 + template/dockerfiles/go/.dockerignore | 2 +- template/dockerfiles/go/Dockerfile | 6 +- template/dockerfiles/go/draft.yaml | 16 +- template/dockerfiles/gomodule/.dockerignore | 2 +- template/dockerfiles/gomodule/Dockerfile | 8 +- template/dockerfiles/gomodule/draft.yaml | 16 +- template/dockerfiles/gradle/.dockerignore | 2 +- template/dockerfiles/gradle/Dockerfile | 8 +- template/dockerfiles/gradle/draft.yaml | 13 + template/dockerfiles/gradlew/.dockerignore | 2 +- template/dockerfiles/gradlew/Dockerfile | 8 +- template/dockerfiles/gradlew/draft.yaml | 15 +- template/dockerfiles/java/.dockerignore | 2 +- template/dockerfiles/java/Dockerfile | 8 +- template/dockerfiles/java/draft.yaml | 13 + template/dockerfiles/javascript/.dockerignore | 2 +- template/dockerfiles/javascript/Dockerfile | 6 +- template/dockerfiles/javascript/draft.yaml | 12 + template/dockerfiles/php/.dockerignore | 2 +- template/dockerfiles/php/Dockerfile | 8 +- template/dockerfiles/php/draft.yaml | 13 + template/dockerfiles/python/.dockerignore | 2 +- template/dockerfiles/python/Dockerfile | 8 +- template/dockerfiles/python/draft.yaml | 13 + template/dockerfiles/ruby/.dockerignore | 2 +- template/dockerfiles/ruby/Dockerfile | 6 +- template/dockerfiles/ruby/draft.yaml | 12 + template/dockerfiles/rust/.dockerignore | 2 +- template/dockerfiles/rust/Dockerfile | 6 +- template/dockerfiles/rust/draft.yaml | 12 + template/dockerfiles/swift/.dockerignore | 2 +- template/dockerfiles/swift/Dockerfile | 6 +- template/dockerfiles/swift/draft.yaml | 12 + .../manifest/draft.yaml | 42 ++ .../manifest/hpa.yaml | 22 ++ .../PodDisruptionBudget/manifest/draft.yaml | 24 ++ .../PodDisruptionBudget/manifest/pdb.yaml | 13 + 154 files changed, 2377 insertions(+), 1761 deletions(-) delete mode 100644 pkg/azurePipelines/azurePipelines.go delete mode 100644 pkg/azurePipelines/azurePipelines_test.go delete mode 100644 pkg/deployments/deployments.go delete mode 100644 pkg/deployments/deployments_test.go rename pkg/fixtures/deployments/{ => helm}/charts/.helmignore (100%) rename pkg/fixtures/deployments/{ => helm}/charts/Chart.yaml (100%) rename pkg/fixtures/deployments/{ => helm}/charts/production.yaml (100%) rename pkg/fixtures/deployments/{ => helm}/charts/templates/_helpers.tpl (100%) rename pkg/fixtures/deployments/{ => helm}/charts/templates/deployment.yaml (100%) rename pkg/fixtures/deployments/{ => helm}/charts/templates/service.yaml (100%) rename pkg/fixtures/deployments/{ => helm}/charts/values.yaml (100%) create mode 100644 pkg/fixtures/deployments/kustomize/base/deployment.yaml create mode 100644 pkg/fixtures/deployments/kustomize/base/kustomization.yaml create mode 100644 pkg/fixtures/deployments/kustomize/base/namespace.yaml create mode 100644 pkg/fixtures/deployments/kustomize/base/service.yaml create mode 100644 pkg/fixtures/deployments/kustomize/overlays/production/deployment.yaml create mode 100644 pkg/fixtures/deployments/kustomize/overlays/production/kustomization.yaml create mode 100644 pkg/fixtures/deployments/kustomize/overlays/production/service.yaml create mode 100644 pkg/fixtures/deployments/manifest/manifests/deployment.yaml create mode 100644 pkg/fixtures/deployments/manifest/manifests/service.yaml create mode 100644 pkg/fixtures/dockerfiles/clojure/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/clojure/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/csharp/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/csharp/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/erlang/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/erlang/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/go/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/go/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/gomodule/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/gomodule/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/gradle/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/gradle/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/gradlew/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/gradlew/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/java/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/java/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/javascript/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/javascript/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/php/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/php/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/python/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/python/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/ruby/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/ruby/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/rust/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/rust/Dockerfile create mode 100644 pkg/fixtures/dockerfiles/swift/.dockerignore create mode 100644 pkg/fixtures/dockerfiles/swift/Dockerfile create mode 100644 pkg/fixtures/workflows/azurepipelines/kustomize/.pipelines/azure-kubernetes-service.yaml create mode 100644 pkg/fixtures/workflows/azurepipelines/manifest/.pipelines/azure-kubernetes-service.yaml create mode 100644 pkg/handlers/template.go create mode 100644 pkg/handlers/template_test.go create mode 100644 pkg/handlers/template_utils.go create mode 100644 pkg/handlers/template_utils_test.go rename pkg/{languages => handlers/variableextractors}/defaults/gradle.go (100%) rename pkg/{languages => handlers/variableextractors}/defaults/gradle_test.go (100%) rename pkg/{languages => handlers/variableextractors}/defaults/python.go (100%) rename pkg/{languages => handlers/variableextractors}/defaults/python_test.go (100%) rename pkg/{languages => handlers/variableextractors}/defaults/testdata/sample.gradle (100%) delete mode 100644 pkg/languages/languages.go delete mode 100644 pkg/languages/languages_test.go create mode 100644 pkg/workflows/manifests/deployment.yaml create mode 100644 pkg/workflows/overlays/production/deployment.yaml create mode 100644 template/README.md delete mode 100644 template/azurePipelines.go delete mode 100644 template/deployments.go delete mode 100644 template/dockerfiles.go create mode 100644 template/manifests/HorizontalPodAutoscaling/manifest/draft.yaml create mode 100644 template/manifests/HorizontalPodAutoscaling/manifest/hpa.yaml create mode 100644 template/manifests/PodDisruptionBudget/manifest/draft.yaml create mode 100644 template/manifests/PodDisruptionBudget/manifest/pdb.yaml diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c42eee18..825e94fd 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,28 +1,28 @@ # Description -Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change. +Please include the related issue if relevant, and motivation/context. Please also list any dependencies required for this change. Fixes # (issue) Feature # (details) ## Type of change -Please delete options that are not relevant. - - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update +- [ ] Refactor -# How Has This Been Tested? +## How Has This Been Tested? -Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Is it a breaking change which will impact consuming tool(s). +Provide instructions so we can reproduce, and list any relevant details for your test configuration. Please mention if this is a breaking change which will impact consuming tool(s). -- [ ] Test A -- [ ] Test B +- [ ] Unit Test: +- [ ] E2E Test: +- [ ] Other Test: -# Checklist: +## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 71943b82..6c3b31db 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -1,10 +1,7 @@ name: draft Unit Tests on: pull_request: - paths: - - '**.go' - - 'go.mod' - - 'go.sum' + branches: [ main ] jobs: build: @@ -16,4 +13,4 @@ jobs: with: go-version: 1.22 - name: make - run: make run-unit-tests \ No newline at end of file + run: make run-unit-tests diff --git a/cmd/create.go b/cmd/create.go index 365d4fb4..c9360930 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -9,6 +9,7 @@ import ( "gopkg.in/yaml.v3" + "github.com/Azure/draft/pkg/handlers" "github.com/Azure/draft/pkg/reporeader" "github.com/Azure/draft/pkg/reporeader/readers" "github.com/manifoldco/promptui" @@ -16,15 +17,12 @@ import ( "github.com/spf13/cobra" "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/deployments" dryrunpkg "github.com/Azure/draft/pkg/dryrun" "github.com/Azure/draft/pkg/filematches" - "github.com/Azure/draft/pkg/languages" "github.com/Azure/draft/pkg/linguist" "github.com/Azure/draft/pkg/prompts" "github.com/Azure/draft/pkg/templatewriter" "github.com/Azure/draft/pkg/templatewriter/writers" - "github.com/Azure/draft/template" ) // ErrNoLanguageDetected is raised when `draft create` does not detect source @@ -52,8 +50,6 @@ type createCmd struct { createConfigPath string createConfig *CreateConfig - supportedLangs *languages.Languages - templateWriter templatewriter.TemplateWriter templateVariableRecorder config.TemplateVariableRecorder repoReader reporeader.RepoReader @@ -151,7 +147,7 @@ func (cc *createCmd) run() error { // detectLanguage detects the language used in a project destination directory // It returns the DraftConfig for that language and the name of the language -func (cc *createCmd) detectLanguage() (*config.DraftConfig, string, error) { +func (cc *createCmd) detectLanguage() (*handlers.Template, string, error) { hasGo := false hasGoMod := false var langs []*linguist.Language @@ -213,44 +209,48 @@ func (cc *createCmd) detectLanguage() (*config.DraftConfig, string, error) { } } - cc.supportedLangs = languages.CreateLanguagesFromEmbedFS(template.Dockerfiles, cc.dest) - if cc.createConfig.LanguageType != "" { log.Debug("using configuration language") lowerLang := strings.ToLower(cc.createConfig.LanguageType) - langConfig := cc.supportedLangs.GetConfig(lowerLang) - if langConfig == nil { - return nil, "", ErrNoLanguageDetected + langDockerfileTemplate, err := handlers.GetTemplate(fmt.Sprintf("dockerfile-%s", lowerLang), "", cc.dest, cc.templateWriter) + if err != nil { + return nil, "", err + } + if langDockerfileTemplate == nil { + return nil, "", fmt.Errorf("could not find a template for %s", cc.createConfig.LanguageType) } - return langConfig, lowerLang, nil + return langDockerfileTemplate, lowerLang, nil } for _, lang := range langs { detectedLang := linguist.Alias(lang) log.Infof("--> Draft detected %s (%f%%)\n", detectedLang.Language, detectedLang.Percent) lowerLang := strings.ToLower(detectedLang.Language) - if cc.supportedLangs.ContainsLanguage(lowerLang) { + if handlers.IsValidTemplate(fmt.Sprintf("dockerfile-%s", lowerLang)) { if lowerLang == "go" && hasGo && hasGoMod { log.Debug("detected go and go module") lowerLang = "gomodule" } - langConfig := cc.supportedLangs.GetConfig(lowerLang) - return langConfig, lowerLang, nil + langDockerfileTemplate, err := handlers.GetTemplate(fmt.Sprintf("dockerfile-%s", lowerLang), "", cc.dest, cc.templateWriter) + if err != nil { + return nil, "", err + } + if langDockerfileTemplate == nil { + return nil, "", fmt.Errorf("could not find a template for detected language %s", detectedLang.Language) + } + return langDockerfileTemplate, lowerLang, nil } log.Infof("--> Could not find a pack for %s. Trying to find the next likely language match...", detectedLang.Language) } return nil, "", ErrNoLanguageDetected } -func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLang string) error { +func (cc *createCmd) generateDockerfile(dockerfileTemplate *handlers.Template, lowerLang string) error { log.Info("--- Dockerfile Creation ---") - if cc.supportedLangs == nil { - return errors.New("supported languages were loaded incorrectly") - } // Extract language-specific defaults from repo - extractedValues, err := cc.supportedLangs.ExtractDefaults(lowerLang, cc.repoReader) + extractedValues, err := dockerfileTemplate.ExtractDefaults(lowerLang, cc.repoReader) if err != nil { return err } @@ -258,15 +258,15 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan // Check for existing duplicate defaults for k, v := range extractedValues { variableExists := false - for i, variable := range langConfig.Variables { + for i, variable := range dockerfileTemplate.Config.Variables { if k == variable.Name { variableExists = true - langConfig.Variables[i].Default.Value = v + dockerfileTemplate.Config.Variables[i].Default.Value = v break } } if !variableExists { - langConfig.Variables = append(langConfig.Variables, &config.BuilderVar{ + dockerfileTemplate.Config.Variables = append(dockerfileTemplate.Config.Variables, &config.BuilderVar{ Name: k, Default: config.BuilderVarDefault{ Value: v, @@ -276,25 +276,25 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan } if cc.createConfig.LanguageVariables == nil { - langConfig.VariableMapToDraftConfig(flagVariablesMap) + dockerfileTemplate.Config.VariableMapToDraftConfig(flagVariablesMap) - if err = prompts.RunPromptsFromConfigWithSkips(langConfig); err != nil { + if err = prompts.RunPromptsFromConfigWithSkips(dockerfileTemplate.Config); err != nil { return err } } else { - err = validateConfigInputsToPrompts(langConfig, cc.createConfig.LanguageVariables) + err = validateConfigInputsToPrompts(dockerfileTemplate.Config, cc.createConfig.LanguageVariables) if err != nil { return err } } if cc.templateVariableRecorder != nil { - for _, variable := range langConfig.Variables { + for _, variable := range dockerfileTemplate.Config.Variables { cc.templateVariableRecorder.Record(variable.Name, variable.Value) } } - if err = cc.supportedLangs.CreateDockerfileForLanguage(lowerLang, langConfig, cc.templateWriter); err != nil { + if err = dockerfileTemplate.Generate(); err != nil { return fmt.Errorf("there was an error when creating the Dockerfile for language %s: %w", cc.createConfig.LanguageType, err) } @@ -304,21 +304,20 @@ func (cc *createCmd) generateDockerfile(langConfig *config.DraftConfig, lowerLan func (cc *createCmd) createDeployment() error { log.Info("--- Deployment File Creation ---") - d := deployments.CreateDeploymentsFromEmbedFS(template.Deployments, cc.dest) var deployType string - var deployConfig *config.DraftConfig + var deployTemplate *handlers.Template var err error if cc.createConfig.DeployType != "" { deployType = strings.ToLower(cc.createConfig.DeployType) - deployConfig, err = d.GetConfig(deployType) + deployTemplate, err = handlers.GetTemplate(fmt.Sprintf("deployment-%s", deployType), "", cc.dest, cc.templateWriter) if err != nil { return err } - if deployConfig == nil { + if deployTemplate == nil || deployTemplate.Config == nil { return errors.New("invalid deployment type") } - err = validateConfigInputsToPrompts(deployConfig, cc.createConfig.DeployVariables) + err = validateConfigInputsToPrompts(deployTemplate.Config, cc.createConfig.DeployVariables) if err != nil { return err } @@ -337,31 +336,34 @@ func (cc *createCmd) createDeployment() error { deployType = cc.deployType } - deployConfig, err = d.GetConfig(deployType) + deployTemplate, err = handlers.GetTemplate(fmt.Sprintf("deployment-%s", deployType), "", cc.dest, cc.templateWriter) if err != nil { return err } - deployConfig.VariableMapToDraftConfig(flagVariablesMap) + if deployTemplate == nil || deployTemplate.Config == nil { + return errors.New("invalid deployment type") + } + + deployTemplate.Config.VariableMapToDraftConfig(flagVariablesMap) - err = prompts.RunPromptsFromConfigWithSkips(deployConfig) + err = prompts.RunPromptsFromConfigWithSkips(deployTemplate.Config) if err != nil { return err } } if cc.templateVariableRecorder != nil { - for _, variable := range deployConfig.Variables { + for _, variable := range deployTemplate.Config.Variables { cc.templateVariableRecorder.Record(variable.Name, variable.Value) } } log.Infof("--> Creating %s Kubernetes resources...\n", deployType) - - return d.CopyDeploymentFiles(deployType, deployConfig, cc.templateWriter) + return deployTemplate.Generate() } -func (cc *createCmd) createFiles(detectedLang *config.DraftConfig, lowerLang string) error { +func (cc *createCmd) createFiles(detectedLangTempalte *handlers.Template, lowerLang string) error { // does no further checks without file detection if cc.dockerfileOnly && cc.deploymentOnly { @@ -370,7 +372,7 @@ func (cc *createCmd) createFiles(detectedLang *config.DraftConfig, lowerLang str if cc.skipFileDetection { if !cc.deploymentOnly { - err := cc.generateDockerfile(detectedLang, lowerLang) + err := cc.generateDockerfile(detectedLangTempalte, lowerLang) if err != nil { return err } @@ -410,7 +412,7 @@ func (cc *createCmd) createFiles(detectedLang *config.DraftConfig, lowerLang str } else if hasDockerFile { log.Info("--> Found Dockerfile in local directory, skipping Dockerfile creation...") } else if !cc.deploymentOnly { - err := cc.generateDockerfile(detectedLang, lowerLang) + err := cc.generateDockerfile(detectedLangTempalte, lowerLang) if err != nil { return err } diff --git a/cmd/create_test.go b/cmd/create_test.go index a4550cce..10714ed0 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -13,16 +13,15 @@ import ( "github.com/stretchr/testify/assert" "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/languages" + "github.com/Azure/draft/pkg/handlers" "github.com/Azure/draft/pkg/linguist" "github.com/Azure/draft/pkg/reporeader" "github.com/Azure/draft/pkg/templatewriter/writers" - "github.com/Azure/draft/template" ) func TestRun(t *testing.T) { - testCreateConfig := CreateConfig{LanguageVariables: []UserInputs{{Name: "PORT", Value: "8080"}}, DeployVariables: []UserInputs{{Name: "PORT", Value: "8080"}, {Name: "APPNAME", Value: "testingCreateCommand"}}} - flagVariablesMap = map[string]string{"PORT": "8080", "APPNAME": "testingCreateCommand", "VERSION": "1.18", "SERVICEPORT": "8080", "NAMESPACE": "testNamespace", "IMAGENAME": "testImage", "IMAGETAG": "latest"} + testCreateConfig := CreateConfig{LanguageVariables: []UserInputs{{Name: "PORT", Value: "8080"}}, DeployVariables: []UserInputs{{Name: "PORT", Value: "8080"}, {Name: "APPNAME", Value: "testingCreateCommand"}, {Name: "DOCKERFILENAME", Value: "Dockerfile"}}} + flagVariablesMap = map[string]string{"PORT": "8080", "APPNAME": "testingCreateCommand", "VERSION": "1.18", "SERVICEPORT": "8080", "NAMESPACE": "testNamespace", "IMAGENAME": "testImage", "IMAGETAG": "latest", "DOCKERFILENAME": "test.Dockerfile"} mockCC := createCmd{ dest: "./..", createConfig: &testCreateConfig, @@ -199,7 +198,7 @@ func TestValidateConfigInputsToPromptsMissing(t *testing.T) { assert.NotNil(t, err) } -func (mcc *createCmd) mockDetectLanguage() (*config.DraftConfig, string, error) { +func (mcc *createCmd) mockDetectLanguage() (*handlers.Template, string, error) { hasGo := false hasGoMod := false var langs []*linguist.Language @@ -227,12 +226,13 @@ func (mcc *createCmd) mockDetectLanguage() (*config.DraftConfig, string, error) } } - mcc.supportedLangs = languages.CreateLanguagesFromEmbedFS(template.Dockerfiles, mcc.dest) - if mcc.createConfig.LanguageType != "" { log.Debug("using configuration language") lowerLang := strings.ToLower(mcc.createConfig.LanguageType) - langConfig := mcc.supportedLangs.GetConfig(lowerLang) + langConfig, err := handlers.GetTemplate(fmt.Sprintf("dockerfile-%s", lowerLang), "", mcc.dest, mcc.templateWriter) + if err != nil { + return nil, "", err + } if langConfig == nil { return nil, "", ErrNoLanguageDetected } @@ -245,13 +245,19 @@ func (mcc *createCmd) mockDetectLanguage() (*config.DraftConfig, string, error) log.Infof("--> Draft detected %s (%f%%)\n", detectedLang.Language, detectedLang.Percent) lowerLang := strings.ToLower(detectedLang.Language) - if mcc.supportedLangs.ContainsLanguage(lowerLang) { + if handlers.IsValidTemplate(fmt.Sprintf("dockerfile-%s", lowerLang)) { if lowerLang == "go" && hasGo && hasGoMod { log.Debug("detected go and go module") lowerLang = "gomodule" } - langConfig := mcc.supportedLangs.GetConfig(lowerLang) + langConfig, err := handlers.GetTemplate(fmt.Sprintf("dockerfile-%s", lowerLang), "", mcc.dest, mcc.templateWriter) + if err != nil { + return nil, "", err + } + if langConfig == nil { + return nil, "", ErrNoLanguageDetected + } return langConfig, lowerLang, nil } log.Infof("--> Could not find a pack for %s. Trying to find the next likely language match...\n", detectedLang.Language) diff --git a/cmd/info.go b/cmd/info.go index 08263752..ee1a2f06 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -7,9 +7,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/Azure/draft/pkg/deployments" - "github.com/Azure/draft/pkg/languages" - "github.com/Azure/draft/template" + "github.com/Azure/draft/pkg/handlers" ) type Format string @@ -18,6 +16,12 @@ const ( JSON Format = "json" ) +var supportedDeploymentTypes = [...]string{ + "helm", + "kustomize", + "manifests", +} + type infoCmd struct { format string info *draftInfo @@ -32,7 +36,7 @@ type draftConfigInfo struct { type draftInfo struct { SupportedLanguages []draftConfigInfo `json:"supportedLanguages"` - SupportedDeploymentTypes []string `json:"supportedDeploymentTypes"` + SupportedDeploymentTypes [3]string `json:"supportedDeploymentTypes"` } func newInfoCmd() *cobra.Command { @@ -56,23 +60,21 @@ func newInfoCmd() *cobra.Command { func (ic *infoCmd) run() error { log.Debugf("getting supported languages") - l := languages.CreateLanguagesFromEmbedFS(template.Dockerfiles, "") - d := deployments.CreateDeploymentsFromEmbedFS(template.Deployments, "") + supportedDockerfileTemplates := handlers.GetTemplatesByType(handlers.TemplateTypeDockerfile) languagesInfo := make([]draftConfigInfo, 0) - for _, lang := range l.Names() { - langConfig := l.GetConfig(lang) + for _, template := range supportedDockerfileTemplates { newConfig := draftConfigInfo{ - Name: lang, - DisplayName: langConfig.DisplayName, - VariableExampleValues: langConfig.GetVariableExampleValues(), + Name: template.Config.TemplateName, + DisplayName: template.Config.DisplayName, + VariableExampleValues: template.Config.GetVariableExampleValues(), } languagesInfo = append(languagesInfo, newConfig) } ic.info = &draftInfo{ SupportedLanguages: languagesInfo, - SupportedDeploymentTypes: d.DeployTypes(), + SupportedDeploymentTypes: supportedDeploymentTypes, } infoText, err := json.MarshalIndent(ic.info, "", " ") diff --git a/cmd/setup-gh.go b/cmd/setup-gh.go index d4862177..d10b4115 100644 --- a/cmd/setup-gh.go +++ b/cmd/setup-gh.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription" "github.com/Azure/draft/pkg/cred" "github.com/Azure/draft/pkg/prompts" @@ -41,6 +42,13 @@ application and service principle, and will configure that application to trust sc.AzClient.AzTenantClient = client + roleAssignmentClient, err := armauthorization.NewRoleAssignmentsClient(sc.SubscriptionID, azCred, nil) + if err != nil { + return fmt.Errorf("getting role assignment client: %w", err) + } + + sc.AzClient.RoleAssignClient = roleAssignmentClient + err = fillSetUpConfig(sc) if err != nil { return fmt.Errorf("filling setup config: %w", err) diff --git a/example/deployment.go b/example/deployment.go index 42ed7d51..095c8d22 100644 --- a/example/deployment.go +++ b/example/deployment.go @@ -3,24 +3,10 @@ package example import ( "fmt" - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/deployments" - "github.com/Azure/draft/pkg/templatewriter" + "github.com/Azure/draft/pkg/handlers" "github.com/Azure/draft/pkg/templatewriter/writers" - "github.com/Azure/draft/template" ) -// WriteDeploymentFiles generates Deployment Files using Draft, writing to a Draft TemplateWriter. See the corresponding draft.yaml file in templates/deployments/[deployType] for the template inputs. -func WriteDeploymentFiles(w templatewriter.TemplateWriter, deploymentOutputPath string, deployConfig *config.DraftConfig, deploymentType string) error { - d := deployments.CreateDeploymentsFromEmbedFS(template.Deployments, deploymentOutputPath) - - err := d.CopyDeploymentFiles(deploymentType, deployConfig, w) - if err != nil { - return fmt.Errorf("failed to generate manifest: %e", err) - } - return nil -} - // WriteDeploymentFilesExample shows how to set up a fileWriter and generate a fileMap using WriteDeploymentFiles func WriteDeploymentFilesExample() error { // Create a file map @@ -32,76 +18,40 @@ func WriteDeploymentFilesExample() error { } // Select the deployment type to generate the files for (must correspond to a directory in the template/deployments directory) - deploymentType := "manifests" + deploymentTemplateType := "deployment-manifests" - // Create a DraftConfig of inputs to the template (must correspond to the inputs in the template/deployments//draft.yaml files) - deployConfig := &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Default: config.BuilderVarDefault{ - Value: "80", - }, - Description: "the port exposed in the application", - Value: "8080", - }, - { - Name: "APPNAME", - Description: "the name of the application", - Value: "example-app", - }, - { - Name: "SERVICEPORT", - Default: config.BuilderVarDefault{ - ReferenceVar: "PORT", - }, - Description: "the port the service uses to make the application accessible from outside the cluster", - Value: "8080", - }, - { - Name: "NAMESPACE", - Default: config.BuilderVarDefault{ - Value: "default", - }, - Description: "the name of the image to use in the deployment", - Value: "example-namespace", - }, - { - Name: "IMAGENAME", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "the name of the image to use in the deployment", - }, - Description: "the name of the image to use in the deployment", - Value: "example-image", - }, - { - Name: "IMAGETAG", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "latest", - }, - Description: "the tag of the image to use in the deployment", - Value: "latest", - }, - { - Name: "GENERATORLABEL", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "draft", - }, - Description: "the label to use to identify the deployment as generated by draft", - }, - }, + // Create a map of of inputs to the template (must correspond to the inputs in the template/deployments//draft.yaml files) + templateVars := map[string]string{ + "PORT": "8080", + "APPNAME": "example-app", + "SERVICEPORT": "8080", + "NAMESPACE": "example-namespace", + "IMAGENAME": "example-image", + "IMAGETAG": "latest", + "GENERATORLABEL": "draft", } // Set the output path for the deployment files outputPath := "./" - // Write the deployment files - err := WriteDeploymentFiles(&w, outputPath, deployConfig, deploymentType) + // Get the deployment template + d, err := handlers.GetTemplate(deploymentTemplateType, "", outputPath, &w) if err != nil { - return err + return fmt.Errorf("failed to get template: %e", err) + } + if d == nil { + return fmt.Errorf("template is nil") + } + + // Set the variable values within the template + for k, v := range templateVars { + d.Config.SetVariable(k, v) + } + + // Generate the deployment files + err = d.Generate() + if err != nil { + return fmt.Errorf("failed to generate manifest: %e", err) } // Read written files from the file map diff --git a/example/deployment_test.go b/example/deployment_test.go index ecb7bdce..af015437 100644 --- a/example/deployment_test.go +++ b/example/deployment_test.go @@ -1,163 +1,9 @@ package example import ( - "fmt" "testing" - - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/templatewriter/writers" ) -func TestWriteDeploymentFiles(t *testing.T) { - filewriter := writers.FileMapWriter{} - outputPath := "test/path" - - testCases := []struct { - name string - deployConfig *config.DraftConfig - deploymentType string - expectError bool - }{ - { - name: "Test Valid Manifests Deployment Generation", - deployConfig: &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Default: config.BuilderVarDefault{ - Value: "80", - }, - Description: "the port exposed in the application", - Value: "8080", - }, - { - Name: "APPNAME", - Description: "the name of the application", - Value: "testapp", - }, - { - Name: "SERVICEPORT", - Default: config.BuilderVarDefault{ - ReferenceVar: "PORT", - }, - Description: "the port the service uses to make the application accessible from outside the cluster", - Value: "8080", - }, - { - Name: "NAMESPACE", - Default: config.BuilderVarDefault{ - Value: "default", - }, - Description: "the name of the image to use in the deployment", - Value: "testnamespace", - }, - { - Name: "IMAGENAME", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "the name of the image to use in the deployment", - }, - Description: "the name of the image to use in the deployment", - Value: "testimage", - }, - { - Name: "IMAGETAG", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "latest", - }, - Description: "the tag of the image to use in the deployment", - Value: "latest", - }, - { - Name: "GENERATORLABEL", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "draft", - }, - Description: "the label to use to identify the deployment as generated by draft", - }, - }, - }, - deploymentType: "manifests", - expectError: false, - }, - { - name: "Test Invalid Manifests Deployment Generation", - deployConfig: &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Default: config.BuilderVarDefault{ - Value: "80", - }, - Description: "the port exposed in the application", - Value: "8080", - }, - { - Name: "APPNAME", - Description: "the name of the application", - }, - { - Name: "SERVICEPORT", - Default: config.BuilderVarDefault{ - ReferenceVar: "PORT", - }, - Description: "the port the service uses to make the application accessible from outside the cluster", - }, - { - Name: "NAMESPACE", - Default: config.BuilderVarDefault{ - Value: "default", - }, - Description: "the name of the image to use in the deployment", - }, - { - Name: "IMAGENAME", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "the name of the image to use in the deployment", - }, - Description: "the name of the image to use in the deployment", - }, - { - Name: "IMAGETAG", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "latest", - }, - Description: "the tag of the image to use in the deployment", - }, - { - Name: "GENERATORLABEL", - Default: config.BuilderVarDefault{ - IsPromptDisabled: true, - Value: "draft", - }, - Description: "the label to use to identify the deployment as generated by draft", - }, - }, - }, - deploymentType: "manifests", - expectError: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := WriteDeploymentFiles(&filewriter, outputPath, tc.deployConfig, tc.deploymentType) - errored := err != nil - if err != nil { - fmt.Printf("WriteDeploymentFiles failed: %e\n", err) - } - if errored != tc.expectError { - t.Errorf("WriteDeploymentFiles failed: expected error %t, got %t", tc.expectError, errored) - t.Fail() - } - }) - } -} - func TestWriteDeploymentFilesExample(t *testing.T) { err := WriteDeploymentFilesExample() if err != nil { diff --git a/example/dockerfile.go b/example/dockerfile.go index 06670284..d3eb5e09 100644 --- a/example/dockerfile.go +++ b/example/dockerfile.go @@ -3,24 +3,10 @@ package example import ( "fmt" - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/languages" - "github.com/Azure/draft/pkg/templatewriter" + "github.com/Azure/draft/pkg/handlers" "github.com/Azure/draft/pkg/templatewriter/writers" - "github.com/Azure/draft/template" ) -// WriteDockerfile generates a Dockerfile and dockerignore using Draft, writing to a Draft TemplateWriter. See the corresponding draft.yaml file in templates/dockerfiles/[language] for the template inputs. -func WriteDockerfile(w templatewriter.TemplateWriter, dockerfileOutputPath string, langConfig *config.DraftConfig, generationLanguage string) error { - l := languages.CreateLanguagesFromEmbedFS(template.Dockerfiles, dockerfileOutputPath) - - err := l.CreateDockerfileForLanguage(generationLanguage, langConfig, w) - if err != nil { - return fmt.Errorf("failed to generate dockerfile: %e", err) - } - return nil -} - // WriteDockerfileExample shows how to set up a fileWriter and generate a fileMap using WriteDockerfile func WriteDockerfileExample() error { // Create a file map @@ -34,27 +20,38 @@ func WriteDockerfileExample() error { // Select the language to generate the Dockerfile for (must correspond to a directory in the template/dockerfiles directory) generationLanguage := "go" - // Create a DraftConfig of inputs to the template (must correspond to the inputs in the template/dockerfiles//draft.yaml files) - langConfig := &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Value: "8080", - }, - { - Name: "VERSION", - Value: "1.20", - }, - }, + // Create a map of inputs to the template (must correspond to the inputs in the template/dockerfiles//draft.yaml files) + templateVars := map[string]string{ + "PORT": "8080", + "APPNAME": "example-app", + "SERVICEPORT": "8080", + "NAMESPACE": "example-namespace", + "IMAGENAME": "example-image", + "IMAGETAG": "latest", + "GENERATORLABEL": "draft", } // Set the output path for the Dockerfile outputPath := "./" - // Write the Dockerfile - err := WriteDockerfile(&w, outputPath, langConfig, generationLanguage) + // Get the dockerfile template + d, err := handlers.GetTemplate(fmt.Sprintf("dockerfile-%s", generationLanguage), "", outputPath, &w) if err != nil { - return err + return fmt.Errorf("failed to get template: %e", err) + } + if d == nil { + return fmt.Errorf("template is nil") + } + + // Set the variable values within the template + for k, v := range templateVars { + d.Config.SetVariable(k, v) + } + + // Generate the dockerfile files + err = d.Generate() + if err != nil { + return fmt.Errorf("failed to generate dockerfile: %e", err) } // Read written files from the file map diff --git a/example/dockerfile_test.go b/example/dockerfile_test.go index 8fd2b6ce..668c2b08 100644 --- a/example/dockerfile_test.go +++ b/example/dockerfile_test.go @@ -1,121 +1,9 @@ package example import ( - "fmt" "testing" - - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/templatewriter/writers" ) -func TestWriteDockerfile(t *testing.T) { - templateWriter := writers.FileMapWriter{} - outputPath := "test/path" - - testCases := []struct { - name string - langConfig *config.DraftConfig - generationLanguage string - expectError bool - }{ - - { - name: "Test Valid Go Dockerfile Generation", - langConfig: &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Default: config.BuilderVarDefault{ - Value: "80", - }, - Description: "the port exposed in the application", - Type: "int", - Value: "8080", - }, - { - Name: "VERSION", - Default: config.BuilderVarDefault{ - Value: "1.18", - }, - Description: "the version of go used by the application", - ExampleValues: []string{"1.16", "1.17", "1.18", "1.19"}, - Value: "1.20", - }, - }, - }, - generationLanguage: "go", - expectError: false, - }, - { - name: "Test Valid Go Dockerfile Generation with default", - langConfig: &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Default: config.BuilderVarDefault{ - Value: "80", - }, - Description: "the port exposed in the application", - Type: "int", - Value: "8080", - }, - { - Name: "VERSION", - Default: config.BuilderVarDefault{ - Value: "1.18", - }, - Description: "the version of go used by the application", - ExampleValues: []string{"1.16", "1.17", "1.18", "1.19"}, - }, - }, - }, - generationLanguage: "go", - expectError: false, - }, - { - name: "Test Invalid GenerationLanguage", - langConfig: &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Default: config.BuilderVarDefault{ - Value: "80", - }, - Description: "the port exposed in the application", - Type: "int", - Value: "8080", - }, - { - Name: "VERSION", - Default: config.BuilderVarDefault{ - Value: "1.18", - }, - Description: "the version of go used by the application", - ExampleValues: []string{"1.16", "1.17", "1.18", "1.19"}, - Value: "1.20", - }, - }, - }, - generationLanguage: "invalid", - expectError: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := WriteDockerfile(&templateWriter, outputPath, tc.langConfig, tc.generationLanguage) - errored := err != nil - if err != nil { - fmt.Printf("WriteDockerfile failed: %e\n", err) - } - if errored != tc.expectError { - t.Errorf("WriteDockerfile failed: expected error %t, got %t", tc.expectError, errored) - t.Fail() - } - }) - } -} - func TestWriteDockerfileExample(t *testing.T) { err := WriteDockerfileExample() if err != nil { diff --git a/go.mod b/go.mod index f31aa034..8d8493e0 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,15 @@ go 1.22.0 require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 + github.com/blang/semver/v4 v4.0.0 github.com/briandowns/spinner v1.23.1 github.com/cenkalti/backoff/v4 v4.3.0 github.com/fatih/color v1.17.0 github.com/ghodss/yaml v1.0.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/go-version v1.7.0 - github.com/instrumenta/kubeval v0.16.1 github.com/ivanpirog/coloredcobra v1.0.1 github.com/jbrukh/bayesian v0.0.0-20231117143245-13ae6f916c7a github.com/manifoldco/promptui v0.9.0 @@ -20,9 +22,11 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 + github.com/yannh/kubeconform v0.6.7 go.uber.org/mock v0.4.0 golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f golang.org/x/mod v0.20.0 + gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.14.4 k8s.io/api v0.29.3 @@ -48,7 +52,6 @@ require ( github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/containerd/containerd v1.7.15 // indirect @@ -83,11 +86,10 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -118,6 +120,7 @@ require ( github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -138,13 +141,13 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect @@ -153,7 +156,6 @@ require ( google.golang.org/protobuf v1.33.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.29.3 // indirect k8s.io/apiserver v0.29.3 // indirect k8s.io/component-base v0.29.3 // indirect diff --git a/go.sum b/go.sum index 396051b5..4438cbb2 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= @@ -19,6 +7,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2 h1:qiir/pptnHqp6hV8QwV+IExYIf6cPsXBfUDUXQ27t2Y= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2/go.mod h1:jVRrRDLCOuif95HDYC23ADTMlvahB7tMdl519m9Iyjc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 h1:UrGzkHueDwAWDdjQxC+QaXHd4tVCkISYE9j7fSSXF8k= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0/go.mod h1:qskvSQeW+cxEE2bcKYyKimB1/KiQ9xpJ99bcHY0BX6c= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= @@ -28,7 +18,6 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= @@ -40,7 +29,6 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= @@ -53,17 +41,12 @@ github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/briandowns/spinner v1.23.1 h1:t5fDPmScwUjozhDj4FA46p5acZWIPXYE30qW2Ptu650= @@ -100,16 +83,10 @@ github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -125,8 +102,6 @@ github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0 github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= @@ -159,8 +134,6 @@ github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= @@ -172,14 +145,12 @@ github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7Dlme github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -205,7 +176,6 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4 github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -213,12 +183,9 @@ github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVI github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -234,8 +201,6 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/cel-go v0.17.7 h1:6ebJFzu1xO2n7TLtN+UBqShGBhlD85bhvglh5DpcfqQ= github.com/google/cel-go v0.17.7/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= @@ -254,59 +219,31 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -316,30 +253,23 @@ github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/instrumenta/kubeval v0.16.1 h1:PticHzCrCqRjwfse1YmlgsN5313Du1PyJ2QnRGVNdVg= -github.com/instrumenta/kubeval v0.16.1/go.mod h1:K9fO5e4B/bznyi5cKzthudanzcPzPBP2OuB5uE9G1TU= github.com/ivanpirog/coloredcobra v1.0.1 h1:aURSdEmlR90/tSiWS0dMjdwOvCVUeYLfltLfbgNxrN4= github.com/ivanpirog/coloredcobra v1.0.1/go.mod h1:iho4nEKcnwZFiniGSdcgdvRgZNjxm+h20acv8vqmN6Q= github.com/jbrukh/bayesian v0.0.0-20231117143245-13ae6f916c7a h1:zSc8tkEGo49/E6cQ9o00si0L9Q/Lu1Hsg8JWKCvzEDU= github.com/jbrukh/bayesian v0.0.0-20231117143245-13ae6f916c7a/go.mod h1:SELxwZQq/mPnfPCR2mchLmT4TQaPJvYtLcCtDWSM7vM= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -351,36 +281,24 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -402,7 +320,6 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= @@ -417,22 +334,17 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc6 h1:XDqvyKsJEbRtATzkgItUqBA7QHk58yxX1Ov9HERHNqU= github.com/opencontainers/image-spec v1.1.0-rc6/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= @@ -442,28 +354,22 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -472,24 +378,14 @@ github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v0.0.0-20180820174524-ff0d02e85550/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -507,21 +403,19 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v0.0.0-20180816142147-da425ebb7609/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yannh/kubeconform v0.6.7 h1:kIvjeiMSU0+/GY48+U9GmJZdGmoej4dArYvv3BfvlyA= +github.com/yannh/kubeconform v0.6.7/go.mod h1:lcx9py+svwYnKXiy146zVstEToiTuTu4rMzdXXfsyVc= github.com/yashtewari/glob-intersection v0.2.0 h1:8iuHdN88yYuCzCdjt0gDe+6bAhUwBeEWqThExu54RFg= github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -533,15 +427,12 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= @@ -564,48 +455,28 @@ go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lI go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -613,17 +484,10 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -631,37 +495,26 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -677,44 +530,27 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -727,32 +563,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2 h1:9IZDv+/GcI6u+a4jRFRLxQs0RUCfavGfoOgEW6jpkI0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= @@ -769,20 +589,14 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -796,10 +610,7 @@ gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= helm.sh/helm/v3 v3.14.4 h1:6FSpEfqyDalHq3kUr4gOMThhgY55kXUEjdQoyODYnrM= helm.sh/helm/v3 v3.14.4/go.mod h1:Tje7LL4gprZpuBNTbG34d1Xn5NmRT3OWfBRwpOSer9I= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= k8s.io/apiextensions-apiserver v0.29.3 h1:9HF+EtZaVpFjStakF4yVufnXGPRppWFEQ87qnO91YeI= @@ -822,7 +633,6 @@ k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSn k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= sigs.k8s.io/controller-runtime v0.17.3 h1:65QmN7r3FWgTxDMz9fvGnO1kbf2nu+acg9p2R9oYYYk= @@ -835,6 +645,5 @@ sigs.k8s.io/kustomize/kyaml v0.17.0 h1:G2bWs03V9Ur2PinHLzTUJ8Ded+30SzXZKiO92SRDs sigs.k8s.io/kustomize/kyaml v0.17.0/go.mod h1:6lxkYF1Cv9Ic8g/N7I86cvxNc5iinUo/P2vKsHNmpyE= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/pkg/azurePipelines/azurePipelines.go b/pkg/azurePipelines/azurePipelines.go deleted file mode 100644 index c46fee1d..00000000 --- a/pkg/azurePipelines/azurePipelines.go +++ /dev/null @@ -1,133 +0,0 @@ -package azurePipelines - -import ( - "embed" - "fmt" - "io/fs" - "path" - - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/embedutils" - "github.com/Azure/draft/pkg/osutil" - "github.com/Azure/draft/pkg/templatewriter" - log "github.com/sirupsen/logrus" - "gopkg.in/yaml.v3" -) - -const ( - pipelineParentDirName = "azurePipelines" - aksPipelineTemplateFileName = "azure-kubernetes-service.yaml" - configFileName = "draft.yaml" - pipelineNameVar = "PIPELINENAME" -) - -type AzurePipelines struct { - pipelines map[string]fs.DirEntry - configs map[string]*config.DraftConfig - dest string - pipelineTemplates embed.FS -} - -func CreatePipelinesFromEmbedFS(pipelineTemplates embed.FS, dest string) (*AzurePipelines, error) { - pipelineMap, err := embedutils.EmbedFStoMap(pipelineTemplates, "azurePipelines") - if err != nil { - return nil, fmt.Errorf("error creating map from embedded FS: %w", err) - } - - p := &AzurePipelines{ - pipelines: pipelineMap, - dest: dest, - configs: make(map[string]*config.DraftConfig), - pipelineTemplates: pipelineTemplates, - } - p.populateConfigs() - - return p, nil - -} - -func (p *AzurePipelines) populateConfigs() { - for _, val := range p.pipelines { - draftConfig, err := p.loadConfig(val.Name()) - if err != nil { - log.Debugf("error loading draftConfig for pipeline of deploy type %s: %v", val.Name(), err) - draftConfig = &config.DraftConfig{} - } - p.configs[val.Name()] = draftConfig - } -} - -func (p *AzurePipelines) GetConfig(deployType string) (*config.DraftConfig, error) { - val, ok := p.configs[deployType] - if !ok { - return nil, fmt.Errorf("deploy type %s unsupported", deployType) - } - return val, nil -} - -func (p *AzurePipelines) loadConfig(deployType string) (*config.DraftConfig, error) { - val, ok := p.pipelines[deployType] - if !ok { - return nil, fmt.Errorf("deploy type %s unsupported", deployType) - } - - configPath := path.Join(pipelineParentDirName, val.Name(), configFileName) - configBytes, err := fs.ReadFile(p.pipelineTemplates, configPath) - if err != nil { - return nil, fmt.Errorf("error reading config file: %w", err) - } - - var draftConfig config.DraftConfig - if err = yaml.Unmarshal(configBytes, &draftConfig); err != nil { - return nil, fmt.Errorf("error unmarshalling config file: %w", err) - } - - return &draftConfig, nil -} - -func (p *AzurePipelines) overrideFilename(draftConfig *config.DraftConfig, srcDir string) error { - if draftConfig.FileNameOverrideMap == nil { - draftConfig.FileNameOverrideMap = make(map[string]string) - } - pipelineVar, err := draftConfig.GetVariable(pipelineNameVar) - if err != nil { - return fmt.Errorf("error getting pipeline name variable: %w", err) - } - - if err = fs.WalkDir(p.pipelineTemplates, srcDir, func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - if d.Name() == aksPipelineTemplateFileName { - draftConfig.FileNameOverrideMap[d.Name()] = pipelineVar.Value + ".yaml" - } - return nil - }); err != nil { - return fmt.Errorf("error walking through source directory: %w", err) - } - - return nil -} - -func (p *AzurePipelines) CreatePipelineFiles(deployType string, draftConfig *config.DraftConfig, templateWriter templatewriter.TemplateWriter) error { - val, ok := p.pipelines[deployType] - if !ok { - return fmt.Errorf("deploy type %s currently unsupported for azure pipeline", deployType) - } - srcDir := path.Join(pipelineParentDirName, val.Name()) - log.Debugf("source directory of pipeline template: %s", srcDir) - - if err := p.overrideFilename(draftConfig, srcDir); err != nil { - return fmt.Errorf("error overriding filename: %w", err) - } - - if err := draftConfig.ApplyDefaultVariables(); err != nil { - return fmt.Errorf("error applying default variables: %w", err) - } - - if err := osutil.CopyDirWithTemplates(p.pipelineTemplates, srcDir, p.dest, draftConfig, templateWriter); err != nil { - return fmt.Errorf("error copying pipeline files: %w", err) - } - - return nil -} diff --git a/pkg/azurePipelines/azurePipelines_test.go b/pkg/azurePipelines/azurePipelines_test.go deleted file mode 100644 index 798d7f4b..00000000 --- a/pkg/azurePipelines/azurePipelines_test.go +++ /dev/null @@ -1,174 +0,0 @@ -package azurePipelines - -import ( - "fmt" - "github.com/Azure/draft/pkg/fixtures" - "os" - "testing" - - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/templatewriter/writers" - "github.com/Azure/draft/template" - "github.com/stretchr/testify/assert" -) - -func TestCreatePipelines(t *testing.T) { - var pipelineFilePath string - templateWriter := &writers.LocalFSWriter{} - - tests := []struct { - name string - deployType string - shouldError bool - setConfig func(dc *config.DraftConfig) - cleanUp func(tempDir string) - }{ - { - name: "kustomize_default_path", - deployType: "kustomize", - shouldError: false, - }, - { - name: "kustomize_given_path", - deployType: "kustomize", - shouldError: false, - setConfig: func(dc *config.DraftConfig) { - dc.SetVariable("KUSTOMIZEPATH", "kustomize/overlays/production") - }, - }, - { - name: "manifests_default_path", - deployType: "manifests", - shouldError: false, - setConfig: func(dc *config.DraftConfig) { - dc.SetVariable("PIPELINENAME", "testPipeline") - }, - }, - { - name: "manifests_custom_path", - deployType: "manifests", - shouldError: false, - setConfig: func(dc *config.DraftConfig) { - dc.SetVariable("MANIFESTPATH", "test/manifests") - }, - }, - { - name: "invalid", - deployType: "invalid", - shouldError: true, - }, - { - name: "missing_config", - deployType: "kustomize", - shouldError: true, - setConfig: func(dc *config.DraftConfig) { - // removing the last variable from draftConfig - dc.Variables = dc.Variables[:len(dc.Variables)-1] - }, - }, - } - - for _, tt := range tests { - draftConfig := newDraftConfig() - - tempDir, err := os.MkdirTemp(".", "testTempDir") - assert.Nil(t, err) - - if tt.setConfig != nil { - tt.setConfig(draftConfig) - } - - pipelines, err := CreatePipelinesFromEmbedFS(template.AzurePipelines, tempDir) - assert.Nil(t, err) - - err = pipelines.CreatePipelineFiles(tt.deployType, draftConfig, templateWriter) - - pipelineFilePath = fmt.Sprintf("%s/.pipelines/%s", tempDir, aksPipelineTemplateFileName) - if val, ok := draftConfig.FileNameOverrideMap[aksPipelineTemplateFileName]; ok { - pipelineFilePath = fmt.Sprintf("%s/.pipelines/%s", tempDir, val) - } - - if tt.shouldError { - assert.NotNil(t, err) - _, err = os.Stat(pipelineFilePath) - assert.Equal(t, os.IsNotExist(err), true) - } else { - assert.Nil(t, err) - _, err = os.Stat(pipelineFilePath) - assert.Nil(t, err) - - // Read the generated content - generatedContent, err := os.ReadFile(pipelineFilePath) - assert.Nil(t, err) - - // Validate against the fixture file - fixturePath := fmt.Sprintf("../fixtures/pipelines/%s.yaml", tt.deployType) - if _, err := os.Stat(fixturePath); os.IsNotExist(err) { - t.Fatalf("Fixture file does not exist at path: %s", fixturePath) - } - - err = fixtures.ValidateContentAgainstFixture(generatedContent, fixturePath) - assert.Nil(t, err) - } - - err = os.RemoveAll(tempDir) - assert.Nil(t, err) - } -} - -func newDraftConfig() *config.DraftConfig { - return &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PIPELINENAME", - Value: "testPipeline", - }, - { - Name: "BRANCHNAME", - Default: config.BuilderVarDefault{ - Value: "main", - }, - }, - { - Name: "ARMSERVICECONNECTION", - Value: "testServiceConnection", - }, - { - Name: "AZURECONTAINERREGISTRY", - Value: "testACR", - }, - { - Name: "CONTAINERNAME", - Value: "testContainer", - }, - { - Name: "CLUSTERRESOURCEGROUP", - Value: "testRG", - }, - { - Name: "ACRRESOURCEGROUP", - Value: "testACRRG", - }, - { - Name: "CLUSTERNAME", - Value: "testCluster", - }, - { - Name: "KUSTOMIZEPATH", - Default: config.BuilderVarDefault{ - Value: "kustomize/overlays/production", - }, - }, - { - Name: "MANIFESTPATH", - Default: config.BuilderVarDefault{ - Value: "test/manifests", - }, - }, - { - Name: "NAMESPACE", - Value: "testNamespace", - }, - }, - } -} diff --git a/pkg/config/draftconfig.go b/pkg/config/draftconfig.go index fc7c57e3..b3f69e94 100644 --- a/pkg/config/draftconfig.go +++ b/pkg/config/draftconfig.go @@ -7,6 +7,8 @@ import ( log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" + + "github.com/blang/semver/v4" ) const draftConfigFile = "draft.yaml" @@ -83,6 +85,19 @@ func (d *DraftConfig) GetVariable(name string) (*BuilderVar, error) { return nil, fmt.Errorf("variable %s not found", name) } +func (d *DraftConfig) GetVariableValue(name string) (string, error) { + for _, variable := range d.Variables { + if variable.Name == name { + if variable.Value == "" { + return "", fmt.Errorf("variable %s has no value", name) + } + return variable.Value, nil + } + } + + return "", fmt.Errorf("variable %s not found", name) +} + func (d *DraftConfig) SetVariable(name, value string) { if variable, err := d.GetVariable(name); err != nil { d.Variables = append(d.Variables, &BuilderVar{ @@ -125,6 +140,62 @@ func (d *DraftConfig) ApplyDefaultVariables() error { return nil } +// ApplyDefaultVariablesForVersion will apply the defaults to variables that are not already set for a specific template version +func (d *DraftConfig) ApplyDefaultVariablesForVersion(version string) error { + v, err := semver.Parse(version) + if err != nil { + return fmt.Errorf("invalid version: %w", err) + } + + expectedConfigVersionRange, err := semver.ParseRange(d.Versions) + if err != nil { + return fmt.Errorf("invalid config version range: %w", err) + } + + if !expectedConfigVersionRange(v) { + return fmt.Errorf("version %s is outside of config version range %s", version, d.Versions) + } + + for _, variable := range d.Variables { + if variable.Value == "" { + expectedRange, err := semver.ParseRange(variable.Versions) + if err != nil { + return fmt.Errorf("invalid variable versions: %w", err) + } + + if !expectedRange(v) { + log.Infof("Variable %s versions %s is outside input version %s, skipping", variable.Name, variable.Versions, version) + continue + } + + if variable.Default.ReferenceVar != "" { + referenceVar, err := d.GetVariable(variable.Default.ReferenceVar) + if err != nil { + return fmt.Errorf("apply default variables: %w", err) + } + + defaultVal, err := d.recurseReferenceVars(referenceVar, referenceVar, true) + if err != nil { + return fmt.Errorf("apply default variables: %w", err) + } + log.Infof("Variable %s defaulting to value %s", variable.Name, defaultVal) + variable.Value = defaultVal + } + + if variable.Value == "" { + if variable.Default.Value != "" { + log.Infof("Variable %s defaulting to value %s", variable.Name, variable.Default.Value) + variable.Value = variable.Default.Value + } else { + return errors.New("variable " + variable.Name + " has no default value") + } + } + } + } + + 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 (d *DraftConfig) recurseReferenceVars(referenceVar *BuilderVar, variableCheck *BuilderVar, isFirst bool) (string, error) { if !isFirst && referenceVar.Name == variableCheck.Name { @@ -154,6 +225,52 @@ func (d *DraftConfig) VariableMapToDraftConfig(flagVariablesMap map[string]strin } } +// SetFileNameOverride sets the filename override for a specific file +func (d *DraftConfig) SetFileNameOverride(input, override string) { + if d.FileNameOverrideMap == nil { + d.FileNameOverrideMap = make(map[string]string) + } + d.FileNameOverrideMap[input] = override +} + +func (d *DraftConfig) DeepCopy() *DraftConfig { + newConfig := &DraftConfig{ + TemplateName: d.TemplateName, + DisplayName: d.DisplayName, + Description: d.Description, + Type: d.Type, + Versions: d.Versions, + DefaultVersion: d.DefaultVersion, + Variables: make([]*BuilderVar, len(d.Variables)), + FileNameOverrideMap: make(map[string]string), + } + for i, variable := range d.Variables { + newConfig.Variables[i] = variable.DeepCopy() + } + + for k, v := range d.FileNameOverrideMap { + newConfig.FileNameOverrideMap[k] = v + } + + return newConfig +} + +func (bv *BuilderVar) DeepCopy() *BuilderVar { + newVar := &BuilderVar{ + Name: bv.Name, + Default: bv.Default, + Description: bv.Description, + Type: bv.Type, + Kind: bv.Kind, + Value: bv.Value, + Versions: bv.Versions, + ExampleValues: make([]string, len(bv.ExampleValues)), + } + + copy(newVar.ExampleValues, bv.ExampleValues) + return newVar +} + // TemplateVariableRecorder is an interface for recording variables that are read using draft configs type TemplateVariableRecorder interface { Record(key, value string) diff --git a/pkg/config/draftconfig_template_test.go b/pkg/config/draftconfig_template_test.go index 7b937100..c7e705a7 100644 --- a/pkg/config/draftconfig_template_test.go +++ b/pkg/config/draftconfig_template_test.go @@ -27,24 +27,29 @@ var validVariableTypes = map[string]bool{ "object": true, } var validVariableKinds = map[string]bool{ - "azureContainerRegistry": true, - "azureKeyvaultUri": true, - "azureManagedCluster": true, - "azureResourceGroup": true, - "azureServiceConnection": true, - "containerImageName": true, - "containerImageVersion": true, - "dirPath": true, - "filePath": true, - "flag": true, - "helmChartOverrides": true, - "ingressHostName": true, - "kubernetesNamespace": true, - "kubernetesResourceName": true, - "label": true, - "port": true, - "repositoryBranch": true, - "workflowName": true, + "azureContainerRegistry": true, + "azureKeyvaultUri": true, + "azureManagedCluster": true, + "azureResourceGroup": true, + "azureServiceConnection": true, + "containerImageName": true, + "containerImageVersion": true, + "dirPath": true, + "dockerFileName": true, + "filePath": true, + "flag": true, + "helmChartOverrides": true, + "ingressHostName": true, + "kubernetesNamespace": true, + "kubernetesResourceName": true, + "label": true, + "port": true, + "repositoryBranch": true, + "workflowName": true, + "replicaCount": true, + "scalingResourceType": true, + "scalingResourceUtilization": true, + "resourceLimit": true, } /* @@ -88,7 +93,7 @@ func loadTemplatesWithValidation() error { return fmt.Errorf("template %s has no template name", path) } - if _, ok := allTemplates[currTemplate.TemplateName]; ok { + if _, ok := allTemplates[strings.ToLower(currTemplate.TemplateName)]; ok { return fmt.Errorf("template %s has a duplicate template name", path) } @@ -96,6 +101,13 @@ func loadTemplatesWithValidation() error { return fmt.Errorf("template %s has an invalid type: %s", path, currTemplate.Type) } + // version range check once we define versions + // if _, err := semver.ParseRange(currTemplate.Versions); err != nil { + // return fmt.Errorf("template %s has an invalid version range: %s", path, currTemplate.Versions) + // } + + referenceVarMap := map[string]*BuilderVar{} + allVariables := map[string]*BuilderVar{} for _, variable := range currTemplate.Variables { if variable.Name == "" { return fmt.Errorf("template %s has a variable with no name", path) @@ -108,7 +120,56 @@ func loadTemplatesWithValidation() error { if _, ok := validVariableKinds[variable.Kind]; !ok { return fmt.Errorf("template %s has an invalid variable kind: %s", path, variable.Kind) } + + // version range check once we define versions + // if _, err := semver.ParseRange(variable.Versions); err != nil { + // return fmt.Errorf("template %s has an invalid version range: %s", path, variable.Versions) + // } + + allVariables[variable.Name] = variable + if variable.Default.ReferenceVar != "" { + referenceVarMap[variable.Name] = variable + } + } + + for _, currVar := range referenceVarMap { + refVar, ok := allVariables[currVar.Default.ReferenceVar] + if !ok { + return fmt.Errorf("template %s has a variable %s with reference to a non-existent variable: %s", path, currVar.Name, currVar.Default.ReferenceVar) + } + + if currVar.Name == refVar.Name { + return fmt.Errorf("template %s has a variable with cyclical reference to itself: %s", path, currVar.Name) + } + + if isCyclicalVariableReference(currVar, refVar, allVariables, map[string]bool{}) { + return fmt.Errorf("template %s has a variable with cyclical reference to itself: %s", path, currVar.Name) + } } + + allTemplates[strings.ToLower(currTemplate.TemplateName)] = currTemplate return nil }) } + +func isCyclicalVariableReference(initialVar, currRefVar *BuilderVar, allVariables map[string]*BuilderVar, visited map[string]bool) bool { + if initialVar.Name == currRefVar.Name { + return true + } + + if _, ok := visited[currRefVar.Name]; ok { + return true + } + + if currRefVar.Default.ReferenceVar == "" { + return false + } + + refVar, ok := allVariables[currRefVar.Default.ReferenceVar] + if !ok { + return false + } + + visited[currRefVar.Name] = true + return isCyclicalVariableReference(initialVar, refVar, allVariables, visited) +} diff --git a/pkg/config/draftconfig_test.go b/pkg/config/draftconfig_test.go index fddf83c5..22c8e223 100644 --- a/pkg/config/draftconfig_test.go +++ b/pkg/config/draftconfig_test.go @@ -197,3 +197,171 @@ func TestApplyDefaultVariables(t *testing.T) { }) } } + +func TestApplyDefaultVariablesForVersion(t *testing.T) { + tests := []struct { + testName string + version string + draftConfig DraftConfig + customInputs map[string]string + want map[string]string + wantErrMsg string + }{ + { + testName: "excludeOutOfVersionRangeVariables", + version: "0.0.1", + draftConfig: DraftConfig{ + Versions: ">=0.0.1 <=0.0.2", + Variables: []*BuilderVar{ + { + Name: "var1", + Value: "", + Versions: ">=0.0.1", + Default: BuilderVarDefault{ + Value: "default-value-1", + }, + }, + { + Name: "var2", + Value: "custom-value-2", + Versions: ">=0.0.2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + want: map[string]string{ + "var1": "default-value-1", + }, + }, + { + testName: "emptyInputVersion", + version: "", + draftConfig: DraftConfig{ + Versions: ">=0.0.1 <=0.0.2", + Variables: []*BuilderVar{ + { + Name: "var1", + Value: "", + Versions: ">=0.0.1", + Default: BuilderVarDefault{ + Value: "default-value-1", + }, + }, + { + Name: "var2", + Value: "", + Versions: ">=0.0.2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + wantErrMsg: "invalid version: Version string empty", + }, + { + testName: "inputVersionOutOfRange", + version: "0.0.3", + draftConfig: DraftConfig{ + Versions: ">=0.0.1 <=0.0.2", + Variables: []*BuilderVar{ + { + Name: "var1", + Value: "", + Versions: ">=0.0.1", + Default: BuilderVarDefault{ + Value: "default-value-1", + }, + }, + { + Name: "var2", + Value: "", + Versions: ">=0.0.2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + wantErrMsg: "version 0.0.3 is outside of config version range >=0.0.1 <=0.0.2", + }, + { + testName: "overwriteDevfaultValue", + version: "0.0.2", + draftConfig: DraftConfig{ + Versions: ">=0.0.1 <=0.0.2", + Variables: []*BuilderVar{ + { + Name: "var1", + Value: "custom-value-1", + Versions: ">=0.0.1", + Default: BuilderVarDefault{ + Value: "default-value-1", + }, + }, + { + Name: "var2", + Value: "custom-value-2", + Versions: ">=0.0.2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + want: map[string]string{ + "var1": "custom-value-1", + "var2": "custom-value-2", + }, + }, + { + testName: "referenceVarOverwrite", + version: "0.0.2", + draftConfig: DraftConfig{ + Versions: ">=0.0.1 <=0.0.2", + Variables: []*BuilderVar{ + { + Name: "var1", + Value: "", + Versions: ">=0.0.1", + Default: BuilderVarDefault{ + ReferenceVar: "var2", + }, + }, + { + Name: "var2", + Value: "custom-value-2", + Versions: ">=0.0.2", + Default: BuilderVarDefault{ + Value: "default-value-2", + }, + }, + }, + }, + want: map[string]string{ + "var1": "custom-value-2", + "var2": "custom-value-2", + }, + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + if err := tt.draftConfig.ApplyDefaultVariablesForVersion(tt.version); err != nil && err.Error() != tt.wantErrMsg { + t.Error(err) + } else { + for k, v := range tt.want { + variable, err := tt.draftConfig.GetVariable(k) + if err != nil { + t.Error(err) + } + + if variable.Value != v { + t.Errorf("got: %s, want: %s, for test: %s", variable.Value, v, tt.testName) + } + } + } + }) + } +} diff --git a/pkg/deployments/deployments.go b/pkg/deployments/deployments.go deleted file mode 100644 index 5275478c..00000000 --- a/pkg/deployments/deployments.go +++ /dev/null @@ -1,111 +0,0 @@ -package deployments - -import ( - "embed" - "fmt" - "io/fs" - "path" - - "golang.org/x/exp/maps" - "gopkg.in/yaml.v3" - - log "github.com/sirupsen/logrus" - - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/embedutils" - "github.com/Azure/draft/pkg/osutil" - "github.com/Azure/draft/pkg/templatewriter" -) - -const ( - parentDirName = "deployments" - configFileName = "draft.yaml" -) - -type Deployments struct { - deploys map[string]fs.DirEntry - configs map[string]*config.DraftConfig - dest string - deploymentTemplates fs.FS -} - -// DeployTypes returns a slice of the supported deployment types -func (d *Deployments) DeployTypes() []string { - names := maps.Keys(d.deploys) - return names -} - -func (d *Deployments) CopyDeploymentFiles(deployType string, deployConfig *config.DraftConfig, templateWriter templatewriter.TemplateWriter) error { - val, ok := d.deploys[deployType] - if !ok { - return fmt.Errorf("deployment type: %s is not currently supported", deployType) - } - - srcDir := path.Join(parentDirName, val.Name()) - - if err := deployConfig.ApplyDefaultVariables(); err != nil { - return fmt.Errorf("create deployment files for deployment type: %w", err) - } - - if err := osutil.CopyDirWithTemplates(d.deploymentTemplates, srcDir, d.dest, deployConfig, templateWriter); err != nil { - return err - } - - return nil -} - -func (d *Deployments) loadConfig(deployType string) (*config.DraftConfig, error) { - val, ok := d.deploys[deployType] - if !ok { - return nil, fmt.Errorf("deployment type %s unsupported", deployType) - } - - configPath := path.Join(parentDirName, val.Name(), configFileName) - configBytes, err := fs.ReadFile(d.deploymentTemplates, configPath) - if err != nil { - return nil, err - } - - var draftConfig config.DraftConfig - if err = yaml.Unmarshal(configBytes, &draftConfig); err != nil { - return nil, err - } - - return &draftConfig, nil -} - -func (d *Deployments) GetConfig(deployType string) (*config.DraftConfig, error) { - val, ok := d.configs[deployType] - if !ok { - return nil, fmt.Errorf("deployment type: %s is not currently supported", deployType) - } - return val, nil -} - -func (d *Deployments) PopulateConfigs() { - for deployType := range d.deploys { - draftConfig, err := d.loadConfig(deployType) - if err != nil { - log.Debugf("no draftConfig found for deployment type %s", deployType) - draftConfig = &config.DraftConfig{} - } - d.configs[deployType] = draftConfig - } -} - -func CreateDeploymentsFromEmbedFS(deploymentTemplates embed.FS, dest string) *Deployments { - deployMap, err := embedutils.EmbedFStoMap(deploymentTemplates, parentDirName) - if err != nil { - log.Fatal(err) - } - - d := &Deployments{ - deploys: deployMap, - dest: dest, - configs: make(map[string]*config.DraftConfig), - deploymentTemplates: deploymentTemplates, - } - d.PopulateConfigs() - - return d -} diff --git a/pkg/deployments/deployments_test.go b/pkg/deployments/deployments_test.go deleted file mode 100644 index 3da9259f..00000000 --- a/pkg/deployments/deployments_test.go +++ /dev/null @@ -1,252 +0,0 @@ -package deployments - -import ( - "embed" - "fmt" - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/embedutils" - "github.com/Azure/draft/pkg/fixtures" - "github.com/Azure/draft/pkg/templatewriter/writers" - "io" - "io/fs" - "os" - "testing" - "testing/fstest" - - "github.com/Azure/draft/template" - "github.com/stretchr/testify/assert" -) - -var testFS embed.FS - -func TestCreateDeployments(t *testing.T) { - dest := "." - templateWriter := &writers.LocalFSWriter{} - draftConfig := &config.DraftConfig{ - Variables: []*config.BuilderVar{ - {Name: "APPNAME", Value: "testapp"}, - {Name: "NAMESPACE", Value: "default"}, - {Name: "PORT", Value: "80"}, - {Name: "IMAGENAME", Value: "testimage"}, - {Name: "IMAGETAG", Value: "latest"}, - {Name: "GENERATORLABEL", Value: "draft"}, - {Name: "SERVICEPORT", Value: "80"}, - }, - } - - tests := []struct { - name string - deployType string - shouldError bool - tempDirPath string - tempFileName string - tempPath string - fixturePath string - cleanUp func() - }{ - { - name: "helm", - deployType: "helm", - shouldError: false, - tempDirPath: "charts/templates", - tempFileName: "charts/templates/deployment.yaml", - tempPath: "../../test/templates/helm/charts/templates/deployment.yaml", - fixturePath: "../fixtures/deployments/charts/templates/deployment.yaml", - cleanUp: func() { - os.Remove(".charts") - }, - }, - { - name: "unsupported", - deployType: "unsupported", - shouldError: true, - tempDirPath: "test/templates/unsupported", - tempFileName: "test/templates/unsupported/deployment.yaml", - tempPath: "test/templates/unsupported/deployment.yaml", - cleanUp: func() { - os.Remove("deployments") - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - fmt.Println("Creating temp file:", tt.tempFileName) - err := createTempDeploymentFile(tt.tempDirPath, tt.tempFileName, tt.tempPath) - assert.Nil(t, err) - - deployments := CreateDeploymentsFromEmbedFS(template.Deployments, dest) - err = deployments.CopyDeploymentFiles(tt.deployType, draftConfig, templateWriter) - if tt.shouldError { - assert.Error(t, err) - } else { - assert.NoError(t, err) - - generatedContent, err := os.ReadFile(tt.tempFileName) - assert.Nil(t, err) - - if _, err := os.Stat(tt.fixturePath); os.IsNotExist(err) { - t.Errorf("Fixture file does not exist at path: %s", tt.fixturePath) - } - - err = fixtures.ValidateContentAgainstFixture(generatedContent, tt.fixturePath) - assert.Nil(t, err) - } - - tt.cleanUp() - }) - } -} - -func TestLoadConfig(t *testing.T) { - fakeFS, err := createMockDeploymentTemplatesFS() - assert.Nil(t, err) - - d, err := createMockDeployments("deployments", fakeFS) - assert.Nil(t, err) - - cases := []loadConfTestCase{ - {"helm", true}, - {"unsupported", false}, - } - - for _, c := range cases { - if c.isNil { - _, err = d.loadConfig(c.deployType) - assert.Nil(t, err) - } else { - _, err = d.loadConfig(c.deployType) - assert.NotNil(t, err) - } - } -} - -func TestPopulateConfigs(t *testing.T) { - fakeFS, err := createMockDeploymentTemplatesFS() - assert.Nil(t, err) - - d, err := createMockDeployments("deployments", fakeFS) - assert.Nil(t, err) - - d.PopulateConfigs() - assert.Equal(t, 3, len(d.configs)) - - d, err = createTestDeploymentEmbed("deployments") - assert.Nil(t, err) - - d.PopulateConfigs() - assert.Equal(t, 3, len(d.configs)) -} - -type loadConfTestCase struct { - deployType string - isNil bool -} - -func createTempDeploymentFile(dirPath, fileName, path string) error { - err := os.MkdirAll(dirPath, 0755) - if err != nil { - return err - } - file, err := os.Create(fileName) - if err != nil { - return err - } - fmt.Printf("file %v\n", file) - defer file.Close() - - var source *os.File - source, err = os.Open(path) - if err != nil { - return err - } - fmt.Printf("source %v\n", source) - defer source.Close() - - _, err = io.Copy(file, source) - if err != nil { - return err - } - return nil -} - -func createMockDeploymentTemplatesFS() (fs.FS, error) { - rootPath := "deplyments/" - embedFiles, err := embedutils.EmbedFStoMapWithFiles(template.Deployments, "deployments") - if err != nil { - return nil, fmt.Errorf("failed to readDir: %w in embeded files", err) - } - - mockFS := fstest.MapFS{} - - for path, file := range embedFiles { - if file.IsDir() { - mockFS[path] = &fstest.MapFile{Mode: fs.ModeDir} - } else { - bytes, err := template.Deployments.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("failes to read file: %w", err) - } - mockFS[path] = &fstest.MapFile{Data: bytes} - } - } - - mockFS[rootPath+"emptyDir"] = &fstest.MapFile{Mode: fs.ModeDir} - mockFS[rootPath+"corrupted"] = &fstest.MapFile{Mode: fs.ModeDir} - mockFS[rootPath+"corrupted/draft.yaml"] = &fstest.MapFile{Data: []byte("fake yaml data")} - - return mockFS, nil -} - -func createMockDeployments(dirPath string, mockDeployments fs.FS) (*Deployments, error) { - dest := "." - - deployMap, err := fsToMap(mockDeployments, dirPath) - if err != nil { - return nil, fmt.Errorf("failed fsToMap: %w", err) - } - - d := &Deployments{ - deploys: deployMap, - dest: dest, - configs: make(map[string]*config.DraftConfig), - deploymentTemplates: mockDeployments, - } - - return d, nil -} - -func createTestDeploymentEmbed(dirPath string) (*Deployments, error) { - dest := "." - - deployMap, err := embedutils.EmbedFStoMap(template.Deployments, "deployments") - if err != nil { - return nil, fmt.Errorf("failed to create deployMap: %w", err) - } - - d := &Deployments{ - deploys: deployMap, - dest: dest, - configs: make(map[string]*config.DraftConfig), - deploymentTemplates: template.Deployments, - } - - return d, nil -} - -func fsToMap(fsFS fs.FS, path string) (map[string]fs.DirEntry, error) { - files, err := fs.ReadDir(fsFS, path) - if err != nil { - return nil, fmt.Errorf("failed to ReadDir: %w", err) - } - - mapping := make(map[string]fs.DirEntry) - - for _, f := range files { - if f.IsDir() { - mapping[f.Name()] = f - } - } - - return mapping, nil -} diff --git a/pkg/filematches/filematches.go b/pkg/filematches/filematches.go index ee7640a7..f282d42d 100644 --- a/pkg/filematches/filematches.go +++ b/pkg/filematches/filematches.go @@ -6,7 +6,7 @@ import ( "os" "path/filepath" - "github.com/instrumenta/kubeval/kubeval" + "github.com/yannh/kubeconform/pkg/validator" ) type FileMatches struct { @@ -43,25 +43,29 @@ func (f *FileMatches) walkFunc(path string, info os.FileInfo, err error) error { // TODO: maybe generalize this function in the future func isValidK8sFile(filePath string) bool { - fileContents, err := os.ReadFile(filePath) + f, err := os.Open(filePath) if err != nil { log.Fatal(err) } - config := kubeval.NewDefaultConfig() - results, err := kubeval.Validate(fileContents, config) - if err != nil || hasErrors(results) { - return false + + v, err := validator.New(nil, validator.Opts{Strict: true}) + if err != nil { + log.Fatalf("failed initializing validator: %s", err) } - return true -} -func hasErrors(res []kubeval.ValidationResult) bool { - for _, r := range res { - if len(r.Errors) > 0 { - return true + for i, res := range v.Validate(filePath, f) { // A file might contain multiple resources + // File starts with ---, the parser assumes a first empty resource + if res.Status == validator.Invalid { + log.Printf("resource %d in file %s is not valid: %s", i, filePath, res.Err) + return false + } + if res.Status == validator.Error { + log.Printf("error while processing resource %d in file %s: %s", i, filePath, res.Err) + return false } } - return false + + return true } func (f *FileMatches) hasDeploymentFiles() bool { diff --git a/pkg/fixtures/deployments/charts/.helmignore b/pkg/fixtures/deployments/helm/charts/.helmignore similarity index 100% rename from pkg/fixtures/deployments/charts/.helmignore rename to pkg/fixtures/deployments/helm/charts/.helmignore diff --git a/pkg/fixtures/deployments/charts/Chart.yaml b/pkg/fixtures/deployments/helm/charts/Chart.yaml similarity index 100% rename from pkg/fixtures/deployments/charts/Chart.yaml rename to pkg/fixtures/deployments/helm/charts/Chart.yaml diff --git a/pkg/fixtures/deployments/charts/production.yaml b/pkg/fixtures/deployments/helm/charts/production.yaml similarity index 100% rename from pkg/fixtures/deployments/charts/production.yaml rename to pkg/fixtures/deployments/helm/charts/production.yaml diff --git a/pkg/fixtures/deployments/charts/templates/_helpers.tpl b/pkg/fixtures/deployments/helm/charts/templates/_helpers.tpl similarity index 100% rename from pkg/fixtures/deployments/charts/templates/_helpers.tpl rename to pkg/fixtures/deployments/helm/charts/templates/_helpers.tpl diff --git a/pkg/fixtures/deployments/charts/templates/deployment.yaml b/pkg/fixtures/deployments/helm/charts/templates/deployment.yaml similarity index 100% rename from pkg/fixtures/deployments/charts/templates/deployment.yaml rename to pkg/fixtures/deployments/helm/charts/templates/deployment.yaml diff --git a/pkg/fixtures/deployments/charts/templates/service.yaml b/pkg/fixtures/deployments/helm/charts/templates/service.yaml similarity index 100% rename from pkg/fixtures/deployments/charts/templates/service.yaml rename to pkg/fixtures/deployments/helm/charts/templates/service.yaml diff --git a/pkg/fixtures/deployments/charts/values.yaml b/pkg/fixtures/deployments/helm/charts/values.yaml similarity index 100% rename from pkg/fixtures/deployments/charts/values.yaml rename to pkg/fixtures/deployments/helm/charts/values.yaml diff --git a/pkg/fixtures/deployments/kustomize/base/deployment.yaml b/pkg/fixtures/deployments/kustomize/base/deployment.yaml new file mode 100644 index 00000000..b3726a27 --- /dev/null +++ b/pkg/fixtures/deployments/kustomize/base/deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: testapp + labels: + app: testapp + kubernetes.azure.com/generator: draft + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: testapp + template: + metadata: + labels: + app: testapp + spec: + containers: + - name: testapp + image: testimage:latest + imagePullPolicy: Always + ports: + - containerPort: 80 \ No newline at end of file diff --git a/pkg/fixtures/deployments/kustomize/base/kustomization.yaml b/pkg/fixtures/deployments/kustomize/base/kustomization.yaml new file mode 100644 index 00000000..ca1d88ef --- /dev/null +++ b/pkg/fixtures/deployments/kustomize/base/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - deployment.yaml + - service.yaml \ No newline at end of file diff --git a/pkg/fixtures/deployments/kustomize/base/namespace.yaml b/pkg/fixtures/deployments/kustomize/base/namespace.yaml new file mode 100644 index 00000000..a3ae0e35 --- /dev/null +++ b/pkg/fixtures/deployments/kustomize/base/namespace.yaml @@ -0,0 +1,6 @@ +kind: Namespace +apiVersion: v1 +metadata: + name: default + labels: + kubernetes.azure.com/generator: draft \ No newline at end of file diff --git a/pkg/fixtures/deployments/kustomize/base/service.yaml b/pkg/fixtures/deployments/kustomize/base/service.yaml new file mode 100644 index 00000000..324d7ecb --- /dev/null +++ b/pkg/fixtures/deployments/kustomize/base/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: testapp + namespace: default + labels: + kubernetes.azure.com/generator: draft +spec: + type: LoadBalancer + selector: + app: testapp + ports: + - protocol: TCP + port: 80 + targetPort: 80 \ No newline at end of file diff --git a/pkg/fixtures/deployments/kustomize/overlays/production/deployment.yaml b/pkg/fixtures/deployments/kustomize/overlays/production/deployment.yaml new file mode 100644 index 00000000..4d836f27 --- /dev/null +++ b/pkg/fixtures/deployments/kustomize/overlays/production/deployment.yaml @@ -0,0 +1,17 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: testapp + labels: + app: testapp + kubernetes.azure.com/generator: draft + namespace: default +spec: + selector: + matchLabels: + app: testapp + template: + spec: + containers: + - name: testapp + image: testimage:latest \ No newline at end of file diff --git a/pkg/fixtures/deployments/kustomize/overlays/production/kustomization.yaml b/pkg/fixtures/deployments/kustomize/overlays/production/kustomization.yaml new file mode 100644 index 00000000..53b1523b --- /dev/null +++ b/pkg/fixtures/deployments/kustomize/overlays/production/kustomization.yaml @@ -0,0 +1,7 @@ +namePrefix: production- +namespace: default +resources: + - ../../base +patchesStrategicMerge: + - deployment.yaml + - service.yaml \ No newline at end of file diff --git a/pkg/fixtures/deployments/kustomize/overlays/production/service.yaml b/pkg/fixtures/deployments/kustomize/overlays/production/service.yaml new file mode 100644 index 00000000..b8a97d3f --- /dev/null +++ b/pkg/fixtures/deployments/kustomize/overlays/production/service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: testapp + namespace: default + labels: + kubernetes.azure.com/generator: draft +spec: + type: LoadBalancer \ No newline at end of file diff --git a/pkg/fixtures/deployments/manifest/manifests/deployment.yaml b/pkg/fixtures/deployments/manifest/manifests/deployment.yaml new file mode 100644 index 00000000..875011a6 --- /dev/null +++ b/pkg/fixtures/deployments/manifest/manifests/deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: testapp + labels: + app: testapp + kubernetes.azure.com/generator: draft + namespace: default + spec: + replicas: 1 + selector: + matchLabels: + app: testapp + template: + metadata: + labels: + app: testapp + spec: + containers: + - name: testapp + image: testimage:latest + imagePullPolicy: Always + ports: + - containerPort: 80 \ No newline at end of file diff --git a/pkg/fixtures/deployments/manifest/manifests/service.yaml b/pkg/fixtures/deployments/manifest/manifests/service.yaml new file mode 100644 index 00000000..324d7ecb --- /dev/null +++ b/pkg/fixtures/deployments/manifest/manifests/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: testapp + namespace: default + labels: + kubernetes.azure.com/generator: draft +spec: + type: LoadBalancer + selector: + app: testapp + ports: + - protocol: TCP + port: 80 + targetPort: 80 \ No newline at end of file diff --git a/pkg/fixtures/dockerfiles/clojure/.dockerignore b/pkg/fixtures/dockerfiles/clojure/.dockerignore new file mode 100644 index 00000000..5b48e5e8 --- /dev/null +++ b/pkg/fixtures/dockerfiles/clojure/.dockerignore @@ -0,0 +1,5 @@ +Dockerfile +charts/ +resources/ +target/ +test/ diff --git a/pkg/fixtures/dockerfiles/clojure/Dockerfile b/pkg/fixtures/dockerfiles/clojure/Dockerfile new file mode 100644 index 00000000..283c5a4c --- /dev/null +++ b/pkg/fixtures/dockerfiles/clojure/Dockerfile @@ -0,0 +1,13 @@ +FROM clojure as BUILD +COPY . /usr/src/app +WORKDIR /usr/src/app +RUN lein ring uberjar + +FROM eclipse-temurin:19-jdk-alpine + +RUN apk update && apk upgrade && apk add bash +ENV PORT 80 +EXPOSE 80 +COPY --from=BUILD /usr/src/app/target/*.jar /opt/ +WORKDIR /opt +CMD ["/bin/bash", "-c", "find -type f -name '*standalone.jar' | xargs java -jar"] diff --git a/pkg/fixtures/dockerfiles/csharp/.dockerignore b/pkg/fixtures/dockerfiles/csharp/.dockerignore new file mode 100644 index 00000000..ac690088 --- /dev/null +++ b/pkg/fixtures/dockerfiles/csharp/.dockerignore @@ -0,0 +1,4 @@ +Dockerfile +charts/ +bin/ +obj/ diff --git a/pkg/fixtures/dockerfiles/csharp/Dockerfile b/pkg/fixtures/dockerfiles/csharp/Dockerfile new file mode 100644 index 00000000..de6c1563 --- /dev/null +++ b/pkg/fixtures/dockerfiles/csharp/Dockerfile @@ -0,0 +1,21 @@ +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS builder +WORKDIR /app + +# caches restore result by copying csproj file separately +COPY *.csproj . +RUN dotnet restore + +COPY . . +RUN dotnet publish --output /app/ --configuration Release --no-restore +RUN sed -n 's:.*\(.*\).*:\1:p' *.csproj > __assemblyname +RUN if [ ! -s __assemblyname ]; then filename=$(ls *.csproj); echo ${filename%.*} > __assemblyname; fi + +# Stage 2 +FROM mcr.microsoft.com/dotnet/aspnet:6.0 +WORKDIR /app +COPY --from=builder /app . + +ENV PORT 80 +EXPOSE 80 + +ENTRYPOINT dotnet $(cat /app/__assemblyname).dll --urls "http://*:80" diff --git a/pkg/fixtures/dockerfiles/erlang/.dockerignore b/pkg/fixtures/dockerfiles/erlang/.dockerignore new file mode 100644 index 00000000..e8513555 --- /dev/null +++ b/pkg/fixtures/dockerfiles/erlang/.dockerignore @@ -0,0 +1,3 @@ +# files and directories to exclude from context +Dockerfile +_build \ No newline at end of file diff --git a/pkg/fixtures/dockerfiles/erlang/Dockerfile b/pkg/fixtures/dockerfiles/erlang/Dockerfile new file mode 100644 index 00000000..8f6c8c35 --- /dev/null +++ b/pkg/fixtures/dockerfiles/erlang/Dockerfile @@ -0,0 +1,40 @@ +FROM erlang:27.0-alpine as builder + +RUN apk add --update tar curl git bash make libc-dev gcc g++ && \ + rm -rf /var/cache/apk/* + +RUN set -xe \ + && curl -fSL -o rebar3 "https://s3.amazonaws.com/rebar3/rebar3" \ + && chmod +x ./rebar3 \ + && ./rebar3 local install \ + && rm ./rebar3 + +WORKDIR /usr/src/app +COPY . /usr/src/app + +ENV PATH "$PATH:/root/.cache/rebar3/bin" +RUN rebar3 as prod tar + +RUN mkdir -p /opt/rel +RUN tar -zxvf /usr/src/app/_build/prod/rel/*/*.tar.gz -C /opt/rel + +RUN relname=$(ls _build/prod/rel) ; echo $relname > /opt/rel/__relname + +FROM alpine:3.17 + +RUN apk add --no-cache openssl-dev ncurses libstdc++ libgcc + +WORKDIR /opt/rel + +ENV RELX_REPLACE_OS_VARS true +ENV HTTP_PORT 80 + +COPY --from=builder /opt/rel /opt/rel + +EXPOSE 80 80 + +RUN ln -s /opt/rel/bin/$(cat /opt/rel/__relname) /opt/rel/bin/start_script +ENTRYPOINT ["/opt/rel/bin/start_script"] + +CMD ["foreground"] + diff --git a/pkg/fixtures/dockerfiles/go/.dockerignore b/pkg/fixtures/dockerfiles/go/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/go/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/go/Dockerfile b/pkg/fixtures/dockerfiles/go/Dockerfile new file mode 100644 index 00000000..83b7699e --- /dev/null +++ b/pkg/fixtures/dockerfiles/go/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:1.23 +ENV PORT=80 +EXPOSE 80 + +WORKDIR /go/src/app +COPY . . + +ARG GO111MODULE=off +RUN go build -v -o app ./main.go +RUN mv ./app /go/bin/ + +CMD ["app"] \ No newline at end of file diff --git a/pkg/fixtures/dockerfiles/gomodule/.dockerignore b/pkg/fixtures/dockerfiles/gomodule/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/gomodule/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/gomodule/Dockerfile b/pkg/fixtures/dockerfiles/gomodule/Dockerfile new file mode 100644 index 00000000..1b334c2b --- /dev/null +++ b/pkg/fixtures/dockerfiles/gomodule/Dockerfile @@ -0,0 +1,16 @@ +FROM golang:1.23 AS builder + +WORKDIR /build +COPY go.mod go.sum ./ +RUN go mod download && go mod verify +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -v -o app-binary + +FROM gcr.io/distroless/static-debian12 + +ENV PORT=80 +EXPOSE 80 + +WORKDIR /app +COPY --from=builder /build/app-binary . +CMD ["/app/app-binary"] diff --git a/pkg/fixtures/dockerfiles/gradle/.dockerignore b/pkg/fixtures/dockerfiles/gradle/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/gradle/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/gradle/Dockerfile b/pkg/fixtures/dockerfiles/gradle/Dockerfile new file mode 100644 index 00000000..61b7926f --- /dev/null +++ b/pkg/fixtures/dockerfiles/gradle/Dockerfile @@ -0,0 +1,13 @@ +FROM gradle:jdk21 as BUILD + +COPY --chown=gradle:gradle . /project +RUN gradle -i -s -b /project/build.gradle clean build + +FROM eclipse-temurin:21-jre +ENV PORT 80 +EXPOSE 80 + +COPY --from=BUILD /project/build/libs/* /opt/ +WORKDIR /opt/ +RUN ls -l +CMD ["/bin/bash", "-c", "find -type f -name '*SNAPSHOT.jar' | xargs java -jar"] diff --git a/pkg/fixtures/dockerfiles/gradlew/.dockerignore b/pkg/fixtures/dockerfiles/gradlew/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/gradlew/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/gradlew/Dockerfile b/pkg/fixtures/dockerfiles/gradlew/Dockerfile new file mode 100644 index 00000000..4c5aede6 --- /dev/null +++ b/pkg/fixtures/dockerfiles/gradlew/Dockerfile @@ -0,0 +1,17 @@ +FROM gradle:jdk21 as BUILD + +COPY --chown=gradle:gradle . /project +COPY gradlew gradlew +COPY gradle/wrapper gradle/wrapper +RUN chmod +x gradle/wrapper +RUN chmod +x gradlew +RUN ./gradlew -i -s -b /project/build.gradle clean build + +FROM eclipse-temurin:21-jre +ENV PORT 80 +EXPOSE 80 + +COPY --from=BUILD /project/build/libs/* /opt/ +WORKDIR /opt/ +RUN ls -l +CMD ["/bin/bash", "-c", "find -type f -name '*SNAPSHOT.jar' | xargs java -jar"] \ No newline at end of file diff --git a/pkg/fixtures/dockerfiles/java/.dockerignore b/pkg/fixtures/dockerfiles/java/.dockerignore new file mode 100644 index 00000000..c81336fd --- /dev/null +++ b/pkg/fixtures/dockerfiles/java/.dockerignore @@ -0,0 +1,5 @@ +Dockerfile +charts/ +target/ +work/ +.git/ diff --git a/pkg/fixtures/dockerfiles/java/Dockerfile b/pkg/fixtures/dockerfiles/java/Dockerfile new file mode 100644 index 00000000..5fd96133 --- /dev/null +++ b/pkg/fixtures/dockerfiles/java/Dockerfile @@ -0,0 +1,12 @@ +FROM maven:3 as BUILD + +COPY . /usr/src/app +RUN mvn --batch-mode -f /usr/src/app/pom.xml clean package + +FROM eclipse-temurin:21-jre +ENV PORT 80 +EXPOSE 80 +COPY --from=BUILD /usr/src/app/target /opt/target +WORKDIR /opt/target + +CMD ["/bin/bash", "-c", "find -type f -name '*-SNAPSHOT.jar' | xargs java -jar"] diff --git a/pkg/fixtures/dockerfiles/javascript/.dockerignore b/pkg/fixtures/dockerfiles/javascript/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/javascript/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/javascript/Dockerfile b/pkg/fixtures/dockerfiles/javascript/Dockerfile new file mode 100644 index 00000000..12be52fd --- /dev/null +++ b/pkg/fixtures/dockerfiles/javascript/Dockerfile @@ -0,0 +1,11 @@ +FROM node:14.15.4 +ENV PORT 80 +EXPOSE 80 + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app +COPY package.json . +RUN npm install +COPY . . + +CMD ["npm", "start"] diff --git a/pkg/fixtures/dockerfiles/php/.dockerignore b/pkg/fixtures/dockerfiles/php/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/php/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/php/Dockerfile b/pkg/fixtures/dockerfiles/php/Dockerfile new file mode 100644 index 00000000..ed650288 --- /dev/null +++ b/pkg/fixtures/dockerfiles/php/Dockerfile @@ -0,0 +1,11 @@ +FROM composer:1 AS build-env +COPY . /app +RUN cd /app && composer install + +FROM php:7.1-apache +ENV PORT 80 +EXPOSE 80 +COPY --from=build-env /app /var/www/html +RUN usermod -u 1000 www-data; \ + a2enmod rewrite; \ + chown -R www-data:www-data /var/www/html diff --git a/pkg/fixtures/dockerfiles/python/.dockerignore b/pkg/fixtures/dockerfiles/python/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/python/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/python/Dockerfile b/pkg/fixtures/dockerfiles/python/Dockerfile new file mode 100644 index 00000000..27d5e8bc --- /dev/null +++ b/pkg/fixtures/dockerfiles/python/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.9 +ENV PORT 80 +EXPOSE 80 +WORKDIR /usr/src/app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +ENTRYPOINT ["python"] +CMD ["app.py"] \ No newline at end of file diff --git a/pkg/fixtures/dockerfiles/ruby/.dockerignore b/pkg/fixtures/dockerfiles/ruby/.dockerignore new file mode 100644 index 00000000..3e5a44ea --- /dev/null +++ b/pkg/fixtures/dockerfiles/ruby/.dockerignore @@ -0,0 +1,3 @@ +Dockerfile +charts/ +tmp/ diff --git a/pkg/fixtures/dockerfiles/ruby/Dockerfile b/pkg/fixtures/dockerfiles/ruby/Dockerfile new file mode 100644 index 00000000..28fccec7 --- /dev/null +++ b/pkg/fixtures/dockerfiles/ruby/Dockerfile @@ -0,0 +1,12 @@ +FROM ruby:3.1.2 +ENV PORT 80 +EXPOSE 80 +RUN bundle config --global frozen 1 + +WORKDIR /usr/src/app + +COPY Gemfile Gemfile.lock ./ +RUN bundle install + +COPY . . +CMD ["ruby", "app.rb"] diff --git a/pkg/fixtures/dockerfiles/rust/.dockerignore b/pkg/fixtures/dockerfiles/rust/.dockerignore new file mode 100644 index 00000000..160b0d8e --- /dev/null +++ b/pkg/fixtures/dockerfiles/rust/.dockerignore @@ -0,0 +1,3 @@ +Dockerfile +charts/ +target diff --git a/pkg/fixtures/dockerfiles/rust/Dockerfile b/pkg/fixtures/dockerfiles/rust/Dockerfile new file mode 100644 index 00000000..5ea25b5f --- /dev/null +++ b/pkg/fixtures/dockerfiles/rust/Dockerfile @@ -0,0 +1,10 @@ +FROM rust:1.70.0 + +WORKDIR /usr/src/app +COPY . /usr/src/app +RUN cargo build + +ENV PORT 80 +EXPOSE 80 + +CMD ["cargo", "run", "-q"] diff --git a/pkg/fixtures/dockerfiles/swift/.dockerignore b/pkg/fixtures/dockerfiles/swift/.dockerignore new file mode 100644 index 00000000..843dec4f --- /dev/null +++ b/pkg/fixtures/dockerfiles/swift/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +charts/ diff --git a/pkg/fixtures/dockerfiles/swift/Dockerfile b/pkg/fixtures/dockerfiles/swift/Dockerfile new file mode 100644 index 00000000..13a0a020 --- /dev/null +++ b/pkg/fixtures/dockerfiles/swift/Dockerfile @@ -0,0 +1,11 @@ +FROM swift:5.5 + +WORKDIR /src +COPY . /src +RUN apt-get update && apt-get install -y sudo openssl libssl-dev libcurl4-openssl-dev +RUN swift build -c release + +ENV PORT 80 +EXPOSE 80 + +CMD ["swift", "run"] diff --git a/pkg/fixtures/validatetemplate.go b/pkg/fixtures/validatetemplate.go index a2c4616a..88ea48f0 100644 --- a/pkg/fixtures/validatetemplate.go +++ b/pkg/fixtures/validatetemplate.go @@ -1,7 +1,6 @@ package fixtures import ( - "embed" "errors" "fmt" "os" @@ -9,17 +8,9 @@ import ( "strings" ) -//go:embed pipelines/* -var pipelines embed.FS - -//go:embed deployments/* -var deployments embed.FS - func ValidateContentAgainstFixture(generatedContent []byte, fixturePath string) error { - fullFixturePath := fmt.Sprintf("%s", fixturePath) - // Read the fixture content - fixtureContent, err := os.ReadFile(fullFixturePath) + fixtureContent, err := os.ReadFile(fixturePath) if err != nil { return fmt.Errorf("failed to read fixture: %w", err) } diff --git a/pkg/fixtures/workflows/azurepipelines/kustomize/.pipelines/azure-kubernetes-service.yaml b/pkg/fixtures/workflows/azurepipelines/kustomize/.pipelines/azure-kubernetes-service.yaml new file mode 100644 index 00000000..3ebda476 --- /dev/null +++ b/pkg/fixtures/workflows/azurepipelines/kustomize/.pipelines/azure-kubernetes-service.yaml @@ -0,0 +1,68 @@ +# Azure Kubernetes Service (AKS) pipeline with Kustomize +# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service cluster + +variables: + armServiceConnection: testserviceconnection + azureContainerRegistry: myacr.acr.io + containerName: myapp + acrRg: myrg + clusterRg: myrg + clusterName: testcluster + kustomizePath: ./overlays/production + namespace: default + tag: "$(Build.BuildId)" + vmImageName: "ubuntu-latest" + +trigger: + - main + +name: Build and deploy an app to AKS + +stages: + - stage: BuildAndPush + displayName: Build stage + jobs: + - job: BuildAndPush + displayName: Build and push image + pool: + vmImage: $(vmImageName) + steps: + - task: AzureCLI@2 + displayName: Build and push image to Azure Container Registry + inputs: + azureSubscription: $(armServiceConnection) + scriptType: "bash" + scriptLocation: "inlineScript" + inlineScript: | + az acr build --image $1.azurecr.io/$2:$3 --registry $1 -g $4 . + arguments: "$(azureContainerRegistry) $(containerName) $(tag) $(acrRg)" + + - stage: Deploy + displayName: Deploy stage + dependsOn: BuildAndPush + jobs: + - job: Deploy + displayName: Deploy to AKS using Kustomize + pool: + vmImage: $(vmImageName) + steps: + - task: KubernetesManifest@1 + displayName: Bake Kustomize manifests + inputs: + action: 'bake' + kustomizationPath: $(kustomizePath) + renderType: 'kustomize' + name: 'bake' + + - task: KubernetesManifest@1 + displayName: Deploy baked manifests to Kubernetes cluster + inputs: + action: 'deploy' + connectionType: 'azureResourceManager' + azureSubscriptionConnection: $(armServiceConnection) + azureResourceGroup: $(clusterRg) + kubernetesCluster: $(clusterName) + namespace: $(namespace) + manifests: $(bake.manifestsBundle) + containers: | + $(azureContainerRegistry).azurecr.io/$(containerName):$(tag) diff --git a/pkg/fixtures/workflows/azurepipelines/manifest/.pipelines/azure-kubernetes-service.yaml b/pkg/fixtures/workflows/azurepipelines/manifest/.pipelines/azure-kubernetes-service.yaml new file mode 100644 index 00000000..c4fd7718 --- /dev/null +++ b/pkg/fixtures/workflows/azurepipelines/manifest/.pipelines/azure-kubernetes-service.yaml @@ -0,0 +1,60 @@ +# Azure Kubernetes Service pipeline +# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service cluster + +variables: + armServiceConnection: testserviceconnection + azureContainerRegistry: myacr.acr.io + containerName: myapp + clusterRg: myrg + acrRg: myrg + clusterName: testcluster + manifestPath: ./manifests + namespace: default + tag: "$(Build.BuildId)" + vmImageName: "ubuntu-latest" + +name: Build and deploy an app to AKS + +trigger: + - main + +stages: + - stage: BuildAndPush + displayName: Build stage + jobs: + - job: BuildAndPush + displayName: Build and push image + pool: + vmImage: $(vmImageName) + steps: + - task: AzureCLI@2 + displayName: Build and push image to Azure Container Registry + inputs: + azureSubscription: $(armServiceConnection) + scriptType: "bash" + scriptLocation: "inlineScript" + inlineScript: | + az acr build --image $1.azurecr.io/$2:$3 --registry $1 -g $4 . + arguments: "$(azureContainerRegistry) $(containerName) $(tag) $(acrRg)" + + - stage: Deploy + displayName: Deploy stage + dependsOn: BuildAndPush + jobs: + - job: Deploy + displayName: Deploy to AKS + pool: + vmImage: $(vmImageName) + steps: + - task: KubernetesManifest@1 + displayName: Deploy to Kubernetes cluster + inputs: + action: "deploy" + connectionType: "azureResourceManager" + azureSubscriptionConnection: $(armServiceConnection) + azureResourceGroup: $(clusterRg) + kubernetesCluster: $(clusterName) + manifests: $(manifestPath) + namespace: $(namespace) + containers: | + $(azureContainerRegistry).azurecr.io/$(containerName):$(tag) diff --git a/pkg/handlers/template.go b/pkg/handlers/template.go new file mode 100644 index 00000000..0c6769ce --- /dev/null +++ b/pkg/handlers/template.go @@ -0,0 +1,198 @@ +package handlers + +import ( + "bytes" + "fmt" + "io/fs" + "path/filepath" + "strings" + tmpl "text/template" + + "github.com/Azure/draft/pkg/config" + "github.com/Azure/draft/pkg/handlers/variableextractors/defaults" + "github.com/Azure/draft/pkg/reporeader" + "github.com/Azure/draft/pkg/templatewriter" + log "github.com/sirupsen/logrus" +) + +type Template struct { + Config *config.DraftConfig + + templateFiles fs.FS + templateWriter templatewriter.TemplateWriter + src string + dest string + version string +} + +// GetTemplate returns a template by name, version, and destination +func GetTemplate(name, version, dest string, templateWriter templatewriter.TemplateWriter) (*Template, error) { + template, ok := templateConfigs[strings.ToLower(name)] + if !ok { + return nil, fmt.Errorf("template not found: %s", name) + } + + template = template.DeepCopy() + + if version == "" { + version = template.Config.DefaultVersion + log.Println("version not provided, using default version: ", version) + } + + if !IsValidVersion(template.Config.Versions, version) { + return nil, fmt.Errorf("invalid version: %s", version) + } + + if dest == "" { + dest = "." + log.Println("destination not provided, using current directory") + } + + if _, err := filepath.Abs(dest); err != nil { + return nil, fmt.Errorf("invalid destination: %s", dest) + } + + template.dest = dest + template.version = version + template.templateWriter = templateWriter + + return template, nil +} + +func (t *Template) Generate() error { + if err := t.validate(); err != nil { + log.Printf("template validation failed: %s", err.Error()) + return err + } + + if err := t.Config.ApplyDefaultVariablesForVersion(t.version); err != nil { + return fmt.Errorf("create workflow files: %w", err) + } + + return generateTemplate(t) +} + +func (t *Template) validate() error { + if t == nil { + return fmt.Errorf("template is nil") + } + + if t.Config == nil { + return fmt.Errorf("template draft config is nil") + } + + if t.src == "" { + return fmt.Errorf("template source is empty") + } + + if t.dest == "" { + return fmt.Errorf("template destination is empty") + } + + if t.templateFiles == nil { + return fmt.Errorf("template files is nil") + } + + if t.version == "" { + return fmt.Errorf("template version is empty") + } + + return nil +} + +func (t *Template) DeepCopy() *Template { + return &Template{ + Config: t.Config.DeepCopy(), + templateFiles: t.templateFiles, + templateWriter: t.templateWriter, + src: t.src, + dest: t.dest, + version: t.version, + } +} + +func (l *Template) ExtractDefaults(lowerLang string, r reporeader.RepoReader) (map[string]string, error) { + extractors := []reporeader.VariableExtractor{ + &defaults.PythonExtractor{}, + &defaults.GradleExtractor{}, + } + extractedValues := make(map[string]string) + if r == nil { + log.Debugf("no repo reader provided, returning empty list of defaults") + return extractedValues, nil + } + for _, extractor := range extractors { + if extractor.MatchesLanguage(lowerLang) { + newDefaults, err := extractor.ReadDefaults(r) + if err != nil { + return nil, fmt.Errorf("error reading defaults for language %s: %v", lowerLang, err) + } + for k, v := range newDefaults { + if _, ok := extractedValues[k]; ok { + log.Debugf("duplicate default %s for language %s with extractor %s", k, lowerLang, extractor.GetName()) + } + extractedValues[k] = v + log.Debugf("extracted default %s=%s with extractor:%s", k, v, extractor.GetName()) + } + } + } + + return extractedValues, nil +} + +func generateTemplate(template *Template) error { + err := fs.WalkDir(template.templateFiles, template.src, func(path string, d fs.DirEntry, err error) error { + if d.IsDir() { + return template.templateWriter.EnsureDirectory(strings.Replace(path, template.src, template.dest, 1)) + } + + if strings.EqualFold(d.Name(), "draft.yaml") { + return nil + } + + if err := writeTemplate(template, path); err != nil { + return fmt.Errorf("failed to write template %s: %w", path, err) + } + + return nil + }) + + return err +} + +func writeTemplate(draftTemplate *Template, inputFile string) error { + file, err := fs.ReadFile(draftTemplate.templateFiles, inputFile) + if err != nil { + return err + } + + // Parse the template file, missingkey=error ensures an error will be returned if any variable is missing during template execution. + tmpl, err := tmpl.New("template").Option("missingkey=error").Parse(string(file)) + if err != nil { + return err + } + + // Execute the template with variableMap + var buf bytes.Buffer + err = tmpl.Execute(&buf, draftTemplate) + if err != nil { + return err + } + + if err = draftTemplate.templateWriter.WriteFile(getOutputFileName(draftTemplate, inputFile), buf.Bytes()); err != nil { + return err + } + + return nil +} + +func getOutputFileName(draftTemplate *Template, inputFile string) string { + outputName := strings.Replace(inputFile, draftTemplate.src, draftTemplate.dest, 1) + + fileName := filepath.Base(inputFile) + if overrideName, ok := draftTemplate.Config.FileNameOverrideMap[fileName]; ok { + return strings.Replace(outputName, fileName, overrideName, 1) + } + + return outputName +} diff --git a/pkg/handlers/template_test.go b/pkg/handlers/template_test.go new file mode 100644 index 00000000..c196cb33 --- /dev/null +++ b/pkg/handlers/template_test.go @@ -0,0 +1,360 @@ +package handlers + +import ( + "fmt" + "path/filepath" + "reflect" + "strings" + "testing" + + "github.com/Azure/draft/pkg/fixtures" + "github.com/Azure/draft/pkg/templatewriter/writers" + "github.com/stretchr/testify/assert" +) + +func TestDeepCopy(t *testing.T) { + // This will fail on adding a new field to the undelying structs that arent handled in DeepCopy + testTemplate, err := GetTemplate("deployment-manifests", "0.0.1", ".", &writers.FileMapWriter{}) + assert.Nil(t, err) + + deepCopy := testTemplate.DeepCopy() + + assert.True(t, reflect.DeepEqual(deepCopy, testTemplate)) +} + +func TestTemplateHandlerValidation(t *testing.T) { + tests := []struct { + name string + templateName string + fixturesBaseDir string + version string + dest string + templateWriter *writers.FileMapWriter + varMap map[string]string + fileNameOverride map[string]string + expectedErr error + }{ + { + name: "valid manifest deployment", + templateName: "deployment-manifests", + fixturesBaseDir: "../fixtures/deployments/manifest", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "APPNAME": "testapp", + "NAMESPACE": "default", + "PORT": "80", + "IMAGENAME": "testimage", + "IMAGETAG": "latest", + "GENERATORLABEL": "draft", + "SERVICEPORT": "80", + }, + }, + { + name: "valid helm deployment", + templateName: "deployment-helm", + fixturesBaseDir: "../fixtures/deployments/helm", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "APPNAME": "testapp", + "NAMESPACE": "default", + "PORT": "80", + "IMAGENAME": "testimage", + "IMAGETAG": "latest", + "GENERATORLABEL": "draft", + "SERVICEPORT": "80", + }, + }, + { + name: "valid kustomize deployment", + templateName: "deployment-kustomize", + fixturesBaseDir: "../fixtures/deployments/kustomize", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "APPNAME": "testapp", + "NAMESPACE": "default", + "PORT": "80", + "IMAGENAME": "testimage", + "IMAGETAG": "latest", + "GENERATORLABEL": "draft", + "SERVICEPORT": "80", + }, + }, + { + name: "valid manifest deployment with filename override", + templateName: "deployment-manifests", + fixturesBaseDir: "../fixtures/deployments/manifest", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "APPNAME": "testapp", + "NAMESPACE": "default", + "PORT": "80", + "IMAGENAME": "testimage", + "IMAGETAG": "latest", + "GENERATORLABEL": "draft", + "SERVICEPORT": "80", + }, + fileNameOverride: map[string]string{ + "deployment.yaml": "deployment-override.yaml", + }, + }, + { + name: "insufficient variables for manifest deployment", + templateName: "deployment-manifests", + fixturesBaseDir: "../fixtures/deployments/manifest", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{}, + expectedErr: fmt.Errorf("create workflow files: variable APPNAME has no default value"), + }, + { + name: "valid clojure dockerfile", + templateName: "dockerfile-clojure", + fixturesBaseDir: "../fixtures/dockerfiles/clojure", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "19-jdk-alpine", + }, + }, + { + name: "valid csharp dockerfile", + templateName: "dockerfile-csharp", + fixturesBaseDir: "../fixtures/dockerfiles/csharp", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "6.0", + }, + }, + { + name: "valid erlang dockerfile", + templateName: "dockerfile-erlang", + fixturesBaseDir: "../fixtures/dockerfiles/erlang", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "BUILDVERSION": "27.0-alpine", + "VERSION": "3.17", + }, + }, + { + name: "valid go dockerfile", + templateName: "dockerfile-go", + fixturesBaseDir: "../fixtures/dockerfiles/go", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "1.23", + }, + }, + { + name: "valid gomodule dockerfile", + templateName: "dockerfile-gomodule", + fixturesBaseDir: "../fixtures/dockerfiles/gomodule", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "1.23", + }, + }, + { + name: "valid gradle dockerfile", + templateName: "dockerfile-gradle", + fixturesBaseDir: "../fixtures/dockerfiles/gradle", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "BUILDVERSION": "jdk21", + "VERSION": "21-jre", + }, + }, + { + name: "valid gradlew dockerfile", + templateName: "dockerfile-gradlew", + fixturesBaseDir: "../fixtures/dockerfiles/gradlew", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "BUILDVERSION": "jdk21", + "VERSION": "21-jre", + }, + }, + { + name: "valid java dockerfile", + templateName: "dockerfile-java", + fixturesBaseDir: "../fixtures/dockerfiles/java", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "BUILDVERSION": "3 (jdk-21)", + "VERSION": "21-jre", + }, + }, + { + name: "valid javascript dockerfile", + templateName: "dockerfile-javascript", + fixturesBaseDir: "../fixtures/dockerfiles/javascript", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "14.15.4", + }, + }, + { + name: "valid php dockerfile", + templateName: "dockerfile-php", + fixturesBaseDir: "../fixtures/dockerfiles/php", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "BUILDVERSION": "1", + "VERSION": "7.1-apache", + }, + }, + { + name: "valid python dockerfile", + templateName: "dockerfile-python", + fixturesBaseDir: "../fixtures/dockerfiles/python", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "ENTRYPOINT": "app.py", + "VERSION": "3.9", + }, + }, + { + name: "valid ruby dockerfile", + templateName: "dockerfile-ruby", + fixturesBaseDir: "../fixtures/dockerfiles/ruby", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "3.1.2", + }, + }, + { + name: "valid rust dockerfile", + templateName: "dockerfile-rust", + fixturesBaseDir: "../fixtures/dockerfiles/rust", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "1.70.0", + }, + }, + { + name: "valid swift dockerfile", + templateName: "dockerfile-swift", + fixturesBaseDir: "../fixtures/dockerfiles/swift", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "PORT": "80", + "VERSION": "5.5", + }, + }, + { + name: "valid azpipeline manifest deployment", + templateName: "azure-pipeline-manifest", + fixturesBaseDir: "../fixtures/workflows/azurepipelines/manifest", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "ARMSERVICECONNECTION": "testserviceconnection", + "AZURECONTAINERREGISTRY": "myacr.acr.io", + "CONTAINERNAME": "myapp", + "CLUSTERRESOURCEGROUP": "myrg", + "ACRRESOURCEGROUP": "myrg", + "CLUSTERNAME": "testcluster", + }, + }, + { + name: "valid azpipeline kustomize deployment", + templateName: "azure-pipeline-kustomize", + fixturesBaseDir: "../fixtures/workflows/azurepipelines/kustomize", + version: "0.0.1", + dest: ".", + templateWriter: &writers.FileMapWriter{}, + varMap: map[string]string{ + "ARMSERVICECONNECTION": "testserviceconnection", + "AZURECONTAINERREGISTRY": "myacr.acr.io", + "CONTAINERNAME": "myapp", + "CLUSTERRESOURCEGROUP": "myrg", + "ACRRESOURCEGROUP": "myrg", + "CLUSTERNAME": "testcluster", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + template, err := GetTemplate(tt.templateName, tt.version, tt.dest, tt.templateWriter) + assert.Nil(t, err) + assert.NotNil(t, template) + + for k, v := range tt.varMap { + template.Config.SetVariable(k, v) + } + + overrideReverseLookup := make(map[string]string) + for k, v := range tt.fileNameOverride { + template.Config.SetFileNameOverride(k, v) + overrideReverseLookup[v] = k + } + + err = template.Generate() + if tt.expectedErr != nil { + assert.Equal(t, tt.expectedErr.Error(), err.Error()) + return + } + assert.Nil(t, err) + + for k, v := range tt.templateWriter.FileMap { + fileName := k + if overrideFile, ok := overrideReverseLookup[filepath.Base(k)]; ok { + fileName = strings.Replace(fileName, filepath.Base(k), overrideFile, 1) + } + + err = fixtures.ValidateContentAgainstFixture(v, fmt.Sprintf("%s/%s", tt.fixturesBaseDir, fileName)) + assert.Nil(t, err) + } + }) + } +} diff --git a/pkg/handlers/template_utils.go b/pkg/handlers/template_utils.go new file mode 100644 index 00000000..ff757f9e --- /dev/null +++ b/pkg/handlers/template_utils.go @@ -0,0 +1,115 @@ +package handlers + +import ( + "fmt" + "io/fs" + "path/filepath" + "runtime" + "strings" + + "github.com/Azure/draft/pkg/config" + "github.com/Azure/draft/template" + "github.com/blang/semver/v4" + log "github.com/sirupsen/logrus" +) + +var templateConfigs map[string]*Template + +type TemplateType string + +func (t TemplateType) String() string { + return string(t) +} + +const ( + TemplateTypeDeployment TemplateType = "deployment" + TemplateTypeDockerfile TemplateType = "dockerfile" + TemplateTypeManifests TemplateType = "manifest" + TemplateTypeWorkflow TemplateType = "workflow" +) + +func init() { + if err := loadTemplates(); err != nil { + log.Fatalf("failed to init templates: %s", err.Error()) + } +} + +// GetTemplates returns all templates +func GetTemplates() map[string]*Template { + return templateConfigs +} + +func GetTemplatesByType(templateType TemplateType) map[string]*Template { + templates := make(map[string]*Template) + for name, template := range templateConfigs { + if template.Config.Type == templateType.String() { + templates[name] = template + } + } + return templates +} + +func IsValidTemplate(templateName string) bool { + _, ok := templateConfigs[strings.ToLower(templateName)] + return ok +} + +func loadTemplates() error { + templateConfigs = make(map[string]*Template) + return fs.WalkDir(template.Templates, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + return nil + } + + if !strings.EqualFold(d.Name(), "draft.yaml") { + return nil + } + + draftConfig, err := config.NewConfigFromFS(template.Templates, path) + if err != nil { + return err + } + + if _, ok := templateConfigs[strings.ToLower(draftConfig.TemplateName)]; ok { + return fmt.Errorf("duplicate template name: %s", draftConfig.TemplateName) + } + + newTemplate := &Template{ + Config: draftConfig, + src: sanatizeTemplateSrcDir(path), + templateFiles: template.Templates, + } + + templateConfigs[strings.ToLower(draftConfig.TemplateName)] = newTemplate + return nil + }) +} + +// IsValidVersion checks if a version is valid for a given version range +func IsValidVersion(versionRange, version string) bool { + v, err := semver.Parse(version) + if err != nil { + return false + } + + expectedRange, err := semver.ParseRange(versionRange) + if err != nil { + return false + } + + return expectedRange(v) +} + +func sanatizeTemplateSrcDir(src string) string { + srcDir := filepath.Dir(src) + + if runtime.GOOS == "windows" { + return strings.ReplaceAll(srcDir, "\\", "/") + } + + return srcDir +} diff --git a/pkg/handlers/template_utils_test.go b/pkg/handlers/template_utils_test.go new file mode 100644 index 00000000..25da381e --- /dev/null +++ b/pkg/handlers/template_utils_test.go @@ -0,0 +1,20 @@ +package handlers + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetTemplate(t *testing.T) { + loadedTemplates := GetTemplates() + assert.Positive(t, len(loadedTemplates)) +} + +func TestLoadTemplates(t *testing.T) { + templateConfigs = nil + err := loadTemplates() + assert.Nil(t, err) + loadedTemplates := GetTemplates() + assert.Positive(t, len(loadedTemplates)) +} diff --git a/pkg/languages/defaults/gradle.go b/pkg/handlers/variableextractors/defaults/gradle.go similarity index 100% rename from pkg/languages/defaults/gradle.go rename to pkg/handlers/variableextractors/defaults/gradle.go diff --git a/pkg/languages/defaults/gradle_test.go b/pkg/handlers/variableextractors/defaults/gradle_test.go similarity index 100% rename from pkg/languages/defaults/gradle_test.go rename to pkg/handlers/variableextractors/defaults/gradle_test.go diff --git a/pkg/languages/defaults/python.go b/pkg/handlers/variableextractors/defaults/python.go similarity index 100% rename from pkg/languages/defaults/python.go rename to pkg/handlers/variableextractors/defaults/python.go diff --git a/pkg/languages/defaults/python_test.go b/pkg/handlers/variableextractors/defaults/python_test.go similarity index 100% rename from pkg/languages/defaults/python_test.go rename to pkg/handlers/variableextractors/defaults/python_test.go diff --git a/pkg/languages/defaults/testdata/sample.gradle b/pkg/handlers/variableextractors/defaults/testdata/sample.gradle similarity index 100% rename from pkg/languages/defaults/testdata/sample.gradle rename to pkg/handlers/variableextractors/defaults/testdata/sample.gradle diff --git a/pkg/languages/languages.go b/pkg/languages/languages.go deleted file mode 100644 index f563012c..00000000 --- a/pkg/languages/languages.go +++ /dev/null @@ -1,146 +0,0 @@ -package languages - -import ( - "embed" - "fmt" - "io/fs" - "path" - - "golang.org/x/exp/maps" - "gopkg.in/yaml.v3" - - "github.com/Azure/draft/pkg/languages/defaults" - "github.com/Azure/draft/pkg/reporeader" - log "github.com/sirupsen/logrus" - - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/embedutils" - "github.com/Azure/draft/pkg/osutil" - "github.com/Azure/draft/pkg/templatewriter" -) - -var ( - parentDirName = "dockerfiles" -) - -type Languages struct { - langs map[string]fs.DirEntry - configs map[string]*config.DraftConfig - dest string - dockerfileTemplates fs.FS -} - -// Names returns a slice of the names of the supported languages -func (l *Languages) Names() []string { - names := maps.Keys(l.langs) - return names -} - -func (l *Languages) ContainsLanguage(lang string) bool { - _, ok := l.langs[lang] - return ok -} - -func (l *Languages) CreateDockerfileForLanguage(lang string, langConfig *config.DraftConfig, templateWriter templatewriter.TemplateWriter) error { - val, ok := l.langs[lang] - if !ok { - return fmt.Errorf("language %s is not supported", lang) - } - - srcDir := path.Join(parentDirName, val.Name()) - - if err := langConfig.ApplyDefaultVariables(); err != nil { - return fmt.Errorf("create dockerfile for language: %w", err) - } - - if err := osutil.CopyDirWithTemplates(l.dockerfileTemplates, srcDir, l.dest, langConfig, templateWriter); err != nil { - return err - } - - return nil -} - -func (l *Languages) loadConfig(lang string) (*config.DraftConfig, error) { - val, ok := l.langs[lang] - if !ok { - return nil, fmt.Errorf("language %s unsupported", lang) - } - - configPath := path.Join(parentDirName, val.Name(), "/draft.yaml") - configBytes, err := fs.ReadFile(l.dockerfileTemplates, configPath) - if err != nil { - return nil, err - } - - var draftConfig config.DraftConfig - if err = yaml.Unmarshal(configBytes, &draftConfig); err != nil { - return nil, err - } - - return &draftConfig, nil -} - -func (l *Languages) GetConfig(lang string) *config.DraftConfig { - val, ok := l.configs[lang] - if !ok { - return nil - } - return val -} - -func (l *Languages) PopulateConfigs() { - for lang := range l.langs { - draftConfig, err := l.loadConfig(lang) - if err != nil { - log.Debugf("no draftConfig found for language %s", lang) - draftConfig = &config.DraftConfig{} - } - l.configs[lang] = draftConfig - } -} - -func CreateLanguagesFromEmbedFS(dockerfileTemplates embed.FS, dest string) *Languages { - langMap, err := embedutils.EmbedFStoMap(dockerfileTemplates, parentDirName) - if err != nil { - log.Fatal(err) - } - - l := &Languages{ - langs: langMap, - dest: dest, - configs: make(map[string]*config.DraftConfig), - dockerfileTemplates: dockerfileTemplates, - } - l.PopulateConfigs() - - return l -} - -func (l *Languages) ExtractDefaults(lowerLang string, r reporeader.RepoReader) (map[string]string, error) { - extractors := []reporeader.VariableExtractor{ - &defaults.PythonExtractor{}, - &defaults.GradleExtractor{}, - } - extractedValues := make(map[string]string) - if r == nil { - log.Debugf("no repo reader provided, returning empty list of defaults") - return extractedValues, nil - } - for _, extractor := range extractors { - if extractor.MatchesLanguage(lowerLang) { - newDefaults, err := extractor.ReadDefaults(r) - if err != nil { - return nil, fmt.Errorf("error reading defaults for language %s: %v", lowerLang, err) - } - for k, v := range newDefaults { - if _, ok := extractedValues[k]; ok { - log.Debugf("duplicate default %s for language %s with extractor %s", k, lowerLang, extractor.GetName()) - } - extractedValues[k] = v - log.Debugf("extracted default %s=%s with extractor:%s", k, v, extractor.GetName()) - } - } - } - - return extractedValues, nil -} diff --git a/pkg/languages/languages_test.go b/pkg/languages/languages_test.go deleted file mode 100644 index d0416915..00000000 --- a/pkg/languages/languages_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package languages - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/Azure/draft/pkg/config" - "github.com/Azure/draft/pkg/templatewriter/writers" - "github.com/Azure/draft/template" -) - -func TestLanguagesCreateDockerfileFileMap(t *testing.T) { - templateWriter := &writers.FileMapWriter{} - l := CreateLanguagesFromEmbedFS(template.Dockerfiles, "/test/dest/dir") - err := l.CreateDockerfileForLanguage("go", &config.DraftConfig{ - Variables: []*config.BuilderVar{ - { - Name: "PORT", - Value: "8080", - }, - { - Name: "VERSION", - Value: "14", - }, - }, - }, templateWriter) - - assert.Nil(t, err) - assert.NotNil(t, templateWriter.FileMap) - assert.NotNil(t, templateWriter.FileMap["/test/dest/dir/Dockerfile"]) -} diff --git a/pkg/providers/az-client.go b/pkg/providers/az-client.go index ccf5dfc0..b20f9c28 100644 --- a/pkg/providers/az-client.go +++ b/pkg/providers/az-client.go @@ -1,15 +1,32 @@ package providers import ( + "fmt" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription" + "github.com/Azure/draft/pkg/cred" ) type AzClient struct { - AzTenantClient azTenantClient + AzTenantClient azTenantClient + RoleAssignClient *armauthorization.RoleAssignmentsClient } //go:generate mockgen -source=./az-client.go -destination=./mock/az-client.go . type azTenantClient interface { NewListPager(options *armsubscription.TenantsClientListOptions) *runtime.Pager[armsubscription.TenantsClientListResponse] } + +func createRoleAssignmentClient(subscriptionId string) (*armauthorization.RoleAssignmentsClient, error) { + credential, err := cred.GetCred() + if err != nil { + return nil, fmt.Errorf("failed to get credentials: %w", err) + } + + client, err := armauthorization.NewRoleAssignmentsClient(subscriptionId, credential, nil) + if err != nil { + return nil, fmt.Errorf("failed to create role assignment client: %w", err) + } + return client, nil +} diff --git a/pkg/providers/azure.go b/pkg/providers/azure.go index 1ad4cd57..ca351806 100644 --- a/pkg/providers/azure.go +++ b/pkg/providers/azure.go @@ -5,10 +5,12 @@ import ( "encoding/json" "errors" "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription" + "github.com/google/uuid" "os/exec" "time" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription" "github.com/Azure/draft/pkg/spinner" bo "github.com/cenkalti/backoff/v4" @@ -61,7 +63,7 @@ func InitiateAzureOIDCFlow(ctx context.Context, sc *SetUpCmd, s spinner.Spinner) return err } - if err := sc.assignSpRole(); err != nil { + if err := sc.assignSpRole(ctx); err != nil { return err } @@ -165,17 +167,36 @@ func (sc *SetUpCmd) CreateServicePrincipal() error { return nil } -func (sc *SetUpCmd) assignSpRole() error { +func (sc *SetUpCmd) assignSpRole(ctx context.Context) error { log.Debug("Assigning contributor role to service principal...") + roleAssignClient, err := createRoleAssignmentClient(sc.SubscriptionID) + if err != nil { + return fmt.Errorf("creating role assignment client: %w", err) + } + scope := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s", sc.SubscriptionID, sc.ResourceGroupName) - assignSpRoleCmd := exec.Command("az", "role", "assignment", "create", "--role", "contributor", "--subscription", sc.SubscriptionID, "--assignee-object-id", sc.spObjectId, "--assignee-principal-type", "ServicePrincipal", "--scope", scope, "--only-show-errors") - out, err := assignSpRoleCmd.CombinedOutput() + objectID := sc.spObjectId + roleId := "b24988ac-6180-42a0-ab88-20f7382dd24c" // Contributor role ID + raUid := uuid.New().String() + + fullAssignmentId := fmt.Sprintf("/%s/providers/Microsoft.Authorization/roleAssignments/%s", scope, raUid) + fullDefinitionId := fmt.Sprintf("/providers/Microsoft.Authorization/roleDefinitions/%s", roleId) + principalType := armauthorization.PrincipalTypeServicePrincipal + parameters := armauthorization.RoleAssignmentCreateParameters{ + Properties: &armauthorization.RoleAssignmentProperties{ + PrincipalID: &objectID, + RoleDefinitionID: &fullDefinitionId, + PrincipalType: &principalType, + }, + } + + _, err = roleAssignClient.CreateByID(ctx, fullAssignmentId, parameters, nil) if err != nil { - log.Printf("%s\n", out) - return err + return fmt.Errorf("creating role assignment: %w", err) } + log.Debug("Role assigned successfully!") return nil } diff --git a/pkg/templatewriter/writers/filemapwriter_test.go b/pkg/templatewriter/writers/filemapwriter_test.go index d184f6de..855960bd 100644 --- a/pkg/templatewriter/writers/filemapwriter_test.go +++ b/pkg/templatewriter/writers/filemapwriter_test.go @@ -13,19 +13,23 @@ import ( func TestCopyDirToFileMap(t *testing.T) { templatewriter := &FileMapWriter{} - err := osutil.CopyDir(template.Dockerfiles, "dockerfiles/javascript", "/test/dir", &config.DraftConfig{ + err := osutil.CopyDir(template.Addons, "addons/azure/webapp_routing", "/test/dir", &config.DraftConfig{ Variables: []*config.BuilderVar{ { - Name: "PORT", - Value: "8080", + Name: "ingress-tls-cert-keyvault-uri", + Value: "https://test.vault.azure.net/secrets/test-secret", }, { - Name: "VERSION", - Value: "14", + Name: "ingress-use-osm-mtls", + Value: "true", + }, + { + Name: "ingress-host", + Value: "testhost.com", }, }, }, templatewriter) assert.Nil(t, err) assert.NotNil(t, templatewriter.FileMap) - assert.NotNil(t, templatewriter.FileMap["/test/dir/Dockerfile"]) + assert.NotNil(t, templatewriter.FileMap["/test/dir/ingress.yaml"]) } diff --git a/pkg/workflows/manifests/deployment.yaml b/pkg/workflows/manifests/deployment.yaml new file mode 100644 index 00000000..d339c904 --- /dev/null +++ b/pkg/workflows/manifests/deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test + labels: + app: test + kubernetes.azure.com/generator: draft +spec: + replicas: 1 + selector: + matchLabels: + app: test + template: + metadata: + labels: + app: test + spec: + containers: + - name: test + image: test + ports: + - containerPort: 8000 \ No newline at end of file diff --git a/pkg/workflows/overlays/production/deployment.yaml b/pkg/workflows/overlays/production/deployment.yaml new file mode 100644 index 00000000..11621fba --- /dev/null +++ b/pkg/workflows/overlays/production/deployment.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test + labels: + kubernetes.azure.com/generator: draft +spec: + template: + spec: + containers: + - name: test + image: acr.test:latest \ No newline at end of file diff --git a/template/README.md b/template/README.md new file mode 100644 index 00000000..d2390baf --- /dev/null +++ b/template/README.md @@ -0,0 +1,43 @@ +# TEMPLATE DEFINITION DOCS + +## Definitions + +All templates are defined within the `./template` directory with a cluster of go template files accompanied by a `draft.yaml` file. + +### draft.yaml + +The `draft.yaml` file contains the metadata needed to define a Template in Draft. The structure of the `draft.yaml` is as follows: + +- `templateName` - The name of the template +- `type` - The type of template +- `description` - Description of template contents/functionality +- `versions` - the range/list of version definitions for this template +- `defaultVersions` - If no version is passed to a template this will be used +- `parameters` - a struct containing information on each parameter to the template + - `name` - the parameter name associated to the gotemplate variable + - `description` - description of what the parameter is used for + - `type` - defines the type of the parameter + - `kind` - defines the kind of parameter, useful for prompting and validation within portal/cli/vsce + - `required` - defines if the parameter is required for the template + - `default` - struct containing information on specific parameters default value + - `value` - the parameters default value + - `referenceVar` - the variable to reference if one is not provided + - `versions` - the versions this item is used for + +For the `type` parameters at the template level we currently have 4 definitions: +- `deployment` - the base k8s deployment + service + namespace +- `dockerfile` - representing a dockerfile for a specific language +- `workflow` - representing a GitHub Action, ADO Pipeline, or similar +- `manifest` - a generic k8s manifest. Think PDB, Ingress, HPA that can be added to an existing `deployment` + +For the `type` parameter at the variable level, this is in line with structured types: `int`, `float`, `string`, `bool`, `object`. + +For the `kind` parameter, this will be used for validation and transformation logic on the input. As an example, `azureResourceGroup` and `azureResourceName` can be validated as defined. + +### Validation + +Within the [draft config teamplate tests](../pkg/config/draftconfig_template_test.go) there is validation logic to make sure all `draft.yaml` definitions adhere to: +- Unique `templateName`'s +- Valid Template `type`'s +- Valid parameter `type`'s +- Valid parameter `kind`'s \ No newline at end of file diff --git a/template/azurePipelines.go b/template/azurePipelines.go deleted file mode 100644 index 5b35c00a..00000000 --- a/template/azurePipelines.go +++ /dev/null @@ -1,8 +0,0 @@ -package template - -import "embed" - -var ( - //go:embed all:azurePipelines - AzurePipelines embed.FS -) diff --git a/template/azurePipelines/kustomize/.pipelines/azure-kubernetes-service.yaml b/template/azurePipelines/kustomize/.pipelines/azure-kubernetes-service.yaml index f307aaed..a9a912a5 100644 --- a/template/azurePipelines/kustomize/.pipelines/azure-kubernetes-service.yaml +++ b/template/azurePipelines/kustomize/.pipelines/azure-kubernetes-service.yaml @@ -2,21 +2,21 @@ # Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service cluster variables: - armServiceConnection: {{.ARMSERVICECONNECTION}} - azureContainerRegistry: {{.AZURECONTAINERREGISTRY}} - containerName: {{.CONTAINERNAME}} - acrRg: {{.ACRRESOURCEGROUP}} - clusterRg: {{.CLUSTERRESOURCEGROUP}} - clusterName: {{.CLUSTERNAME}} - kustomizePath: {{.KUSTOMIZEPATH}} - namespace: {{.NAMESPACE}} + armServiceConnection: {{ .Config.GetVariableValue "ARMSERVICECONNECTION" }} + azureContainerRegistry: {{ .Config.GetVariableValue "AZURECONTAINERREGISTRY" }} + containerName: {{ .Config.GetVariableValue "CONTAINERNAME" }} + acrRg: {{ .Config.GetVariableValue "ACRRESOURCEGROUP" }} + clusterRg: {{ .Config.GetVariableValue "CLUSTERRESOURCEGROUP" }} + clusterName: {{ .Config.GetVariableValue "CLUSTERNAME" }} + kustomizePath: {{ .Config.GetVariableValue "KUSTOMIZEPATH" }} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} tag: "$(Build.BuildId)" vmImageName: "ubuntu-latest" trigger: - - {{.BRANCHNAME}} + - {{ .Config.GetVariableValue "BRANCHNAME" }} -name: {{.PIPELINENAME}} +name: {{ .Config.GetVariableValue "PIPELINENAME" }} {{` stages: - stage: BuildAndPush diff --git a/template/azurePipelines/kustomize/draft.yaml b/template/azurePipelines/kustomize/draft.yaml index 3c81762e..205ea36d 100644 --- a/template/azurePipelines/kustomize/draft.yaml +++ b/template/azurePipelines/kustomize/draft.yaml @@ -1,5 +1,7 @@ templateName: "azure-pipeline-kustomize" description: "This template is used to create an Azure Pipeline for deploying an app to AKS using Kustomize" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "workflow" variables: - name: "PIPELINENAME" @@ -8,36 +10,44 @@ variables: default: value: "Build and deploy an app to AKS" description: "the name of the azure pipeline" + versions: ">=0.0.1" - name: "BRANCHNAME" type: "string" kind: "repositoryBranch" default: value: "main" description: "the branch to trigger the pipeline" + versions: ">=0.0.1" - name: "ARMSERVICECONNECTION" type: "string" kind: "azureServiceConnection" description: "the name of the Azure Resource Manager service connection" + versions: ">=0.0.1" - name: "AZURECONTAINERREGISTRY" type: "string" kind: "azureContainerRegistry" description: "the name of the Azure Container Registry" + versions: ">=0.0.1" - name: "CONTAINERNAME" type: "string" kind: "containerImageName" description: "the container image name" + versions: ">=0.0.1" - name: "CLUSTERRESOURCEGROUP" type: "string" kind: "azureResourceGroup" description: "the AKS cluster resource group" + versions: ">=0.0.1" - name: "ACRRESOURCEGROUP" type: "string" kind: "azureResourceGroup" description: "the ACR resource group" + versions: ">=0.0.1" - name: "CLUSTERNAME" type: "string" kind: "azureManagedCluster" description: "the AKS cluster name" + versions: ">=0.0.1" - name: "KUSTOMIZEPATH" type: "string" kind: "dirPath" @@ -45,9 +55,11 @@ variables: disablePrompt: true value: "./overlays/production" # keeping this as default since draft generates the manifests in the overlays/production directory description: "the path to the Kustomize directory" + versions: ">=0.0.1" - name: "NAMESPACE" type: "string" kind: "kubernetesNamespace" default: value: "default" description: "the Kubernetes namespace" + versions: ">=0.0.1" diff --git a/template/azurePipelines/manifests/.pipelines/azure-kubernetes-service.yaml b/template/azurePipelines/manifests/.pipelines/azure-kubernetes-service.yaml index 10ef1d38..1f963d1c 100644 --- a/template/azurePipelines/manifests/.pipelines/azure-kubernetes-service.yaml +++ b/template/azurePipelines/manifests/.pipelines/azure-kubernetes-service.yaml @@ -2,21 +2,21 @@ # Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service cluster variables: - armServiceConnection: {{.ARMSERVICECONNECTION}} - azureContainerRegistry: {{.AZURECONTAINERREGISTRY}} - containerName: {{.CONTAINERNAME}} - clusterRg: {{.CLUSTERRESOURCEGROUP}} - acrRg: {{.ACRRESOURCEGROUP}} - clusterName: {{.CLUSTERNAME}} - manifestPath: {{.MANIFESTPATH}} - namespace: {{.NAMESPACE}} + armServiceConnection: {{ .Config.GetVariableValue "ARMSERVICECONNECTION" }} + azureContainerRegistry: {{ .Config.GetVariableValue "AZURECONTAINERREGISTRY" }} + containerName: {{ .Config.GetVariableValue "CONTAINERNAME" }} + clusterRg: {{ .Config.GetVariableValue "CLUSTERRESOURCEGROUP" }} + acrRg: {{ .Config.GetVariableValue "ACRRESOURCEGROUP" }} + clusterName: {{ .Config.GetVariableValue "CLUSTERNAME" }} + manifestPath: {{ .Config.GetVariableValue "MANIFESTPATH" }} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} tag: "$(Build.BuildId)" vmImageName: "ubuntu-latest" -name: {{.PIPELINENAME}} +name: {{ .Config.GetVariableValue "PIPELINENAME" }} trigger: - - {{.BRANCHNAME}} + - {{ .Config.GetVariableValue "BRANCHNAME" }} {{` stages: - stage: BuildAndPush diff --git a/template/azurePipelines/manifests/draft.yaml b/template/azurePipelines/manifests/draft.yaml index b124e0bb..755c0e51 100644 --- a/template/azurePipelines/manifests/draft.yaml +++ b/template/azurePipelines/manifests/draft.yaml @@ -1,5 +1,7 @@ templateName: "azure-pipeline-manifest" description: "Azure Pipeline for deploying a containerized application to AKS using kubernetes manifests" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "workflow" variables: - name: "PIPELINENAME" @@ -8,36 +10,44 @@ variables: default: value: "Build and deploy an app to AKS" description: "the name of the azure pipeline" + versions: ">=0.0.1" - name: "BRANCHNAME" type: "string" kind: "repositoryBranch" default: value: "main" description: "the branch to trigger the pipeline" + versions: ">=0.0.1" - name: "ARMSERVICECONNECTION" type: "string" kind: "azureServiceConnection" description: "the name of the Azure Resource Manager service connection" + versions: ">=0.0.1" - name: "AZURECONTAINERREGISTRY" type: "string" kind: "azureContainerRegistry" description: "the name of the Azure Container Registry" + versions: ">=0.0.1" - name: "CONTAINERNAME" type: "string" kind: "containerImageName" description: "the container image name" + versions: ">=0.0.1" - name: "CLUSTERRESOURCEGROUP" type: "string" kind: "azureResourceGroup" description: "the AKS cluster resource group" + versions: ">=0.0.1" - name: "ACRRESOURCEGROUP" type: "string" kind: "azureResourceGroup" description: "the ACR resource group" + versions: ">=0.0.1" - name: "CLUSTERNAME" type: "string" kind: "azureManagedCluster" description: "the AKS cluster name" + versions: ">=0.0.1" - name: "MANIFESTPATH" type: "string" kind: "dirPath" @@ -45,9 +55,11 @@ variables: disablePrompt: true value: "./manifests" description: "the path to the Kubernetes deployment manifest" + versions: ">=0.0.1" - name: "NAMESPACE" type: "string" kind: "kubernetesNamespace" default: value: "default" description: "the Kubernetes namespace" + versions: ">=0.0.1" diff --git a/template/deployments.go b/template/deployments.go deleted file mode 100644 index a4c112b3..00000000 --- a/template/deployments.go +++ /dev/null @@ -1,8 +0,0 @@ -package template - -import "embed" - -var ( - //go:embed all:deployments - Deployments embed.FS -) diff --git a/template/deployments/helm/charts/Chart.yaml b/template/deployments/helm/charts/Chart.yaml index 4480aa68..f76a9eda 100644 --- a/template/deployments/helm/charts/Chart.yaml +++ b/template/deployments/helm/charts/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -name: {{.APPNAME}} +name: {{ .Config.GetVariableValue "APPNAME" }} description: A Helm chart for Kubernetes # A chart can be either an 'application' or a 'library' chart. diff --git a/template/deployments/helm/charts/production.yaml b/template/deployments/helm/charts/production.yaml index 36e67ec8..98ee21e7 100644 --- a/template/deployments/helm/charts/production.yaml +++ b/template/deployments/helm/charts/production.yaml @@ -1,8 +1,8 @@ image: - repository: "{{.APPNAME}}" + repository: "{{ .Config.GetVariableValue "APPNAME" }}" pullPolicy: Always tag: "latest" service: annotations: {} type: LoadBalancer - port: "{{.SERVICEPORT}}" + port: "{{ .Config.GetVariableValue "SERVICEPORT" }}" diff --git a/template/deployments/helm/charts/templates/_helpers.tpl b/template/deployments/helm/charts/templates/_helpers.tpl index 30222bcc..00ffbdb0 100644 --- a/template/deployments/helm/charts/templates/_helpers.tpl +++ b/template/deployments/helm/charts/templates/_helpers.tpl @@ -1,7 +1,7 @@ {{/* Expand the name of the chart. */}} -{{ printf "{{- define \"%s.name\" -}}" .APPNAME }} +{{ .Config.GetVariableValue "APPNAME" | printf "{{- define \"%s.name\" -}}" }} {{`{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }}`}} @@ -10,7 +10,7 @@ Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} -{{ printf "{{- define \"%s.fullname\" -}}" .APPNAME }} +{{ .Config.GetVariableValue "APPNAME" | printf "{{- define \"%s.fullname\" -}}" }} {{`{{- if .Values.fullnameOverride }} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} {{- else }} @@ -26,16 +26,16 @@ If release name contains chart name it will be used as a full name. {{/* Create chart name and version as used by the chart label. */}} -{{ printf "{{- define \"%s.chart\" -}}" .APPNAME }} +{{ .Config.GetVariableValue "APPNAME" | printf "{{- define \"%s.chart\" -}}" }} {{`{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }}`}} {{/* Common labels */}} -{{ printf "{{- define \"%s.labels\" -}}" .APPNAME }} -helm.sh/chart: {{ printf "{{ include \"%s.chart\" . }}" .APPNAME }} -{{ printf "{{ include \"%s.selectorLabels\" . }}" .APPNAME }} +{{ .Config.GetVariableValue "APPNAME" | printf "{{- define \"%s.labels\" -}}" }} +helm.sh/chart: {{ .Config.GetVariableValue "APPNAME" | printf "{{ include \"%s.chart\" . }}" }} +{{ .Config.GetVariableValue "APPNAME" | printf "{{ include \"%s.selectorLabels\" . }}" }} {{`{{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -45,5 +45,5 @@ app.kubernetes.io/managed-by: {{ .Release.Service }} {{/* Selector labels */}} -{{ printf "{{- define \"%s.selectorLabels\" -}}" .APPNAME }} -{{ printf "app.kubernetes.io/name: {{ include \"%s.name\" . }}\napp.kubernetes.io/instance: {{ .Release.Name }}\n{{- end }}" .APPNAME }} \ No newline at end of file +{{ .Config.GetVariableValue "APPNAME" | printf "{{- define \"%s.selectorLabels\" -}}" }} +{{ .Config.GetVariableValue "APPNAME" | printf "app.kubernetes.io/name: {{ include \"%s.name\" . }}\napp.kubernetes.io/instance: {{ .Release.Name }}\n{{- end }}" }} \ No newline at end of file diff --git a/template/deployments/helm/charts/templates/deployment.yaml b/template/deployments/helm/charts/templates/deployment.yaml index dd1537e0..5ebad8e7 100644 --- a/template/deployments/helm/charts/templates/deployment.yaml +++ b/template/deployments/helm/charts/templates/deployment.yaml @@ -1,9 +1,9 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ printf "{{ include \"%s.fullname\" . }}" .APPNAME }} + name: {{ .Config.GetVariableValue "APPNAME" | printf "{{ include \"%s.fullname\" . }}" }} labels: - {{ printf "{{- include \"%s.labels\" . | nindent 4 }}" .APPNAME }} + {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.labels\" . | nindent 4 }}" }} {{- ` kubernetes.azure.com/generator: {{ .Values.generatorLabel }} namespace: {{ .Values.namespace }} @@ -16,7 +16,7 @@ spec: ` -}} selector: matchLabels: - {{ printf "{{- include \"%s.selectorLabels\" . | nindent 6 }}" .APPNAME }} + {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.selectorLabels\" . | nindent 6 }}" }} template: metadata: {{- ` @@ -26,7 +26,7 @@ spec: {{- end }} ` -}} labels: - {{ printf "{{- include \"%s.selectorLabels\" . | nindent 8 }}" .APPNAME }} + {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.selectorLabels\" . | nindent 8 }}" }} namespace: {{ print "{{ .Values.namespace }}" }} spec: {{- ` diff --git a/template/deployments/helm/charts/templates/service.yaml b/template/deployments/helm/charts/templates/service.yaml index 5bc87795..f7fdea76 100644 --- a/template/deployments/helm/charts/templates/service.yaml +++ b/template/deployments/helm/charts/templates/service.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: Service metadata: - name: {{ printf "{{ include \"%s.fullname\" . }}" .APPNAME }} + name: {{ .Config.GetVariableValue "APPNAME" | printf "{{ include \"%s.fullname\" . }}" }} labels: - {{ printf "{{- include \"%s.labels\" . | nindent 4 }}" .APPNAME }} + {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.labels\" . | nindent 4 }}" }} {{- ` kubernetes.azure.com/generator: {{.Values.generatorLabel}} annotations: @@ -20,4 +20,4 @@ spec: name: svchttp ` -}} selector: - {{ printf "{{- include \"%s.selectorLabels\" . | nindent 6 }}" .APPNAME }} + {{ .Config.GetVariableValue "APPNAME" | printf "{{- include \"%s.selectorLabels\" . | nindent 6 }}" }} diff --git a/template/deployments/helm/charts/values.yaml b/template/deployments/helm/charts/values.yaml index 321227f8..c8347edd 100644 --- a/template/deployments/helm/charts/values.yaml +++ b/template/deployments/helm/charts/values.yaml @@ -1,18 +1,17 @@ -# Default values for {{.APPNAME}}. +# Default values for {{ .Config.GetVariableValue "APPNAME"}}. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 1 -namespace: {{.NAMESPACE}} +namespace: {{ .Config.GetVariableValue "NAMESPACE" }} -containerPort: {{.PORT}} +containerPort: {{ .Config.GetVariableValue "PORT" }} image: - repository: {{.IMAGENAME}} - tag: {{.IMAGETAG}} + repository: {{ .Config.GetVariableValue "IMAGENAME" }} + tag: {{ .Config.GetVariableValue "IMAGETAG" }} pullPolicy: Always - imagePullSecrets: [] nameOverride: "" fullnameOverride: "" @@ -33,7 +32,7 @@ securityContext: {} service: annotations: {} type: LoadBalancer - port: {{.SERVICEPORT}} + port: {{ .Config.GetVariableValue "SERVICEPORT" }} resources: {} # We usually recommend not to specify default resources and to leave this as a conscious @@ -60,4 +59,4 @@ tolerations: [] affinity: {} -generatorLabel: {{.GENERATORLABEL}} \ No newline at end of file +generatorLabel: {{ .Config.GetVariableValue "GENERATORLABEL" }} \ No newline at end of file diff --git a/template/deployments/helm/draft.yaml b/template/deployments/helm/draft.yaml index eaae9017..dcd8d2b3 100644 --- a/template/deployments/helm/draft.yaml +++ b/template/deployments/helm/draft.yaml @@ -1,6 +1,8 @@ templateName: "deployment-helm" description: "This template is used to create a Helm deployment for an application" type: "deployment" +versions: "0.0.1" +defaultVersion: "0.0.1" variables: - name: "PORT" type: "int" @@ -8,28 +10,33 @@ variables: default: value: 80 description: "the port exposed in the application" + versions: ">=0.0.1" - name: "APPNAME" type: "string" kind: "kubernetesResourceName" description: "the name of the application" + versions: ">=0.0.1" - name: "SERVICEPORT" type: "int" kind: "port" default: referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" + versions: ">=0.0.1" - name: "NAMESPACE" type: "string" kind: "kubernetesNamespace" default: value: default description: " the namespace to place new resources in" + versions: ">=0.0.1" - name: "IMAGENAME" type: "string" kind: "containerImageName" default: referenceVar: "APPNAME" description: "the name of the image to use in the deployment" + versions: ">=0.0.1" - name: "IMAGETAG" type: "string" kind: "containerImageVersion" @@ -37,6 +44,7 @@ variables: disablePrompt: true value: "latest" description: "the tag of the image to use in the deployment" + versions: ">=0.0.1" - name: "GENERATORLABEL" type: "string" kind: "label" @@ -44,3 +52,4 @@ variables: disablePrompt: true value: "draft" description: "the label to identify who generated the resource" + versions: ">=0.0.1" diff --git a/template/deployments/kustomize/base/deployment.yaml b/template/deployments/kustomize/base/deployment.yaml index 4e07bd64..ad05db20 100644 --- a/template/deployments/kustomize/base/deployment.yaml +++ b/template/deployments/kustomize/base/deployment.yaml @@ -1,24 +1,24 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{.APPNAME}} + name: {{ .Config.GetVariableValue "APPNAME" }} labels: - app: {{.APPNAME}} - kubernetes.azure.com/generator: {{.GENERATORLABEL}} - namespace: {{.NAMESPACE}} + app: {{ .Config.GetVariableValue "APPNAME"}} + kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} spec: replicas: 1 selector: matchLabels: - app: {{.APPNAME}} + app: {{ .Config.GetVariableValue "APPNAME" }} template: metadata: labels: - app: {{.APPNAME}} + app: {{ .Config.GetVariableValue "APPNAME" }} spec: containers: - - name: {{.APPNAME}} - image: {{.IMAGENAME}}:{{.IMAGETAG}} + - name: {{.Config.GetVariableValue "APPNAME" }} + image: {{ .Config.GetVariableValue "IMAGENAME" }}:{{ .Config.GetVariableValue "IMAGETAG" }} imagePullPolicy: Always ports: - - containerPort: {{.PORT}} \ No newline at end of file + - containerPort: {{ .Config.GetVariableValue "PORT" }} \ No newline at end of file diff --git a/template/deployments/kustomize/base/namespace.yaml b/template/deployments/kustomize/base/namespace.yaml index 76a4a407..d88099a4 100644 --- a/template/deployments/kustomize/base/namespace.yaml +++ b/template/deployments/kustomize/base/namespace.yaml @@ -1,6 +1,6 @@ kind: Namespace apiVersion: v1 metadata: - name: {{.NAMESPACE}} + name: {{ .Config.GetVariableValue "NAMESPACE" }} labels: - kubernetes.azure.com/generator: {{.GENERATORLABEL}} \ No newline at end of file + kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} \ No newline at end of file diff --git a/template/deployments/kustomize/base/service.yaml b/template/deployments/kustomize/base/service.yaml index 83481aa4..7503816d 100644 --- a/template/deployments/kustomize/base/service.yaml +++ b/template/deployments/kustomize/base/service.yaml @@ -1,15 +1,15 @@ apiVersion: v1 kind: Service metadata: - name: {{.APPNAME}} - namespace: {{.NAMESPACE}} + name: {{ .Config.GetVariableValue "APPNAME" }} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} labels: - kubernetes.azure.com/generator: {{.GENERATORLABEL}} + kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} spec: type: LoadBalancer selector: - app: {{.APPNAME}} + app: {{ .Config.GetVariableValue "APPNAME" }} ports: - protocol: TCP - port: {{.SERVICEPORT}} - targetPort: {{.PORT}} \ No newline at end of file + port: {{ .Config.GetVariableValue "SERVICEPORT" }} + targetPort: {{ .Config.GetVariableValue "PORT" }} \ No newline at end of file diff --git a/template/deployments/kustomize/draft.yaml b/template/deployments/kustomize/draft.yaml index d8b79d0d..56ce1068 100644 --- a/template/deployments/kustomize/draft.yaml +++ b/template/deployments/kustomize/draft.yaml @@ -1,4 +1,6 @@ templateName: "deployment-kustomize" +versions: "0.0.1" +defaultVersion: "0.0.1" description: "This template is used to create a Kustomize deployment for an application" type: "deployment" variables: @@ -8,28 +10,33 @@ variables: default: value: 80 description: "the port exposed in the application" + versions: ">=0.0.1" - name: "APPNAME" type: "string" kind: "kubernetesResourceName" description: "the name of the application" + versions: ">=0.0.1" - name: "SERVICEPORT" type: "int" kind: "port" default: referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" + versions: ">=0.0.1" - name: "NAMESPACE" type: "string" kind: "kubernetesNamespace" default: value: default description: " the namespace to place new resources in" + versions: ">=0.0.1" - name: "IMAGENAME" type: "string" kind: "containerImageName" default: referenceVar: "APPNAME" description: "the name of the image to use in the deployment" + versions: ">=0.0.1" - name: "IMAGETAG" type: "string" kind: "containerImageVersion" @@ -37,6 +44,7 @@ variables: disablePrompt: true value: "latest" description: "the tag of the image to use in the deployment" + versions: ">=0.0.1" - name: "GENERATORLABEL" type: "string" kind: "label" @@ -44,3 +52,4 @@ variables: disablePrompt: true value: "draft" description: "the label to identify who generated the resource" + versions: ">=0.0.1" diff --git a/template/deployments/kustomize/overlays/production/deployment.yaml b/template/deployments/kustomize/overlays/production/deployment.yaml index 0929b145..df3a7ed4 100644 --- a/template/deployments/kustomize/overlays/production/deployment.yaml +++ b/template/deployments/kustomize/overlays/production/deployment.yaml @@ -1,17 +1,17 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{.APPNAME}} + name: {{ .Config.GetVariableValue "APPNAME" }} labels: - app: {{.APPNAME}} - kubernetes.azure.com/generator: {{.GENERATORLABEL}} - namespace: {{.NAMESPACE}} + app: {{ .Config.GetVariableValue "APPNAME" }} + kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL"}} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} spec: selector: matchLabels: - app: {{.APPNAME}} + app: {{ .Config.GetVariableValue "APPNAME" }} template: spec: containers: - - name: {{.APPNAME}} - image: {{.IMAGENAME}}:{{.IMAGETAG}} \ No newline at end of file + - name: {{ .Config.GetVariableValue "APPNAME" }} + image: {{ .Config.GetVariableValue "IMAGENAME" }}:{{ .Config.GetVariableValue "IMAGETAG" }} \ No newline at end of file diff --git a/template/deployments/kustomize/overlays/production/kustomization.yaml b/template/deployments/kustomize/overlays/production/kustomization.yaml index d13c9cee..8411218f 100644 --- a/template/deployments/kustomize/overlays/production/kustomization.yaml +++ b/template/deployments/kustomize/overlays/production/kustomization.yaml @@ -1,5 +1,5 @@ namePrefix: production- -namespace: {{.NAMESPACE}} +namespace: {{ .Config.GetVariableValue "NAMESPACE" }} resources: - ../../base patchesStrategicMerge: diff --git a/template/deployments/kustomize/overlays/production/service.yaml b/template/deployments/kustomize/overlays/production/service.yaml index 70afda67..1edb9e84 100644 --- a/template/deployments/kustomize/overlays/production/service.yaml +++ b/template/deployments/kustomize/overlays/production/service.yaml @@ -1,9 +1,9 @@ apiVersion: v1 kind: Service metadata: - name: {{.APPNAME}} - namespace: {{.NAMESPACE}} + name: {{ .Config.GetVariableValue "APPNAME"}} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} labels: - kubernetes.azure.com/generator: {{.GENERATORLABEL}} + kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} spec: - type: LoadBalancer + type: LoadBalancer \ No newline at end of file diff --git a/template/deployments/manifests/draft.yaml b/template/deployments/manifests/draft.yaml index 168794ad..e946e009 100644 --- a/template/deployments/manifests/draft.yaml +++ b/template/deployments/manifests/draft.yaml @@ -1,5 +1,7 @@ -templateName: "deployment-manifest" +templateName: "deployment-manifests" description: "This template is used to create a Kubernetes manifest deployment for an application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "deployment" variables: - name: "PORT" @@ -8,28 +10,33 @@ variables: default: value: 80 description: "the port exposed in the application" + versions: ">=0.0.1" - name: "APPNAME" type: "string" kind: "kubernetesResourceName" description: "the name of the application" + versions: ">=0.0.1" - name: "SERVICEPORT" type: "int" kind: "port" default: referenceVar: "PORT" description: "the port the service uses to make the application accessible from outside the cluster" + versions: ">=0.0.1" - name: "NAMESPACE" type: "string" kind: "kubernetesNamespace" default: value: default description: " the namespace to place new resources in" + versions: ">=0.0.1" - name: "IMAGENAME" type: "string" kind: "containerImageName" default: referenceVar: "APPNAME" description: "the name of the image to use in the deployment" + versions: ">=0.0.1" - name: "IMAGETAG" type: "string" kind: "containerImageVersion" @@ -37,6 +44,7 @@ variables: disablePrompt: true value: "latest" description: "the tag of the image to use in the deployment" + versions: ">=0.0.1" - name: "GENERATORLABEL" type: "string" kind: "label" @@ -44,3 +52,4 @@ variables: disablePrompt: true value: "draft" description: "the label to identify who generated the resource" + versions: ">=0.0.1" diff --git a/template/deployments/manifests/manifests/deployment.yaml b/template/deployments/manifests/manifests/deployment.yaml index 4e07bd64..c8d88cea 100644 --- a/template/deployments/manifests/manifests/deployment.yaml +++ b/template/deployments/manifests/manifests/deployment.yaml @@ -1,24 +1,24 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{.APPNAME}} + name: {{ .Config.GetVariableValue "APPNAME" }} labels: - app: {{.APPNAME}} - kubernetes.azure.com/generator: {{.GENERATORLABEL}} - namespace: {{.NAMESPACE}} + app: {{ .Config.GetVariableValue "APPNAME" }} + kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} spec: replicas: 1 selector: matchLabels: - app: {{.APPNAME}} + app: {{ .Config.GetVariableValue "APPNAME" }} template: metadata: labels: - app: {{.APPNAME}} + app: {{ .Config.GetVariableValue "APPNAME" }} spec: containers: - - name: {{.APPNAME}} - image: {{.IMAGENAME}}:{{.IMAGETAG}} + - name: {{ .Config.GetVariableValue "APPNAME" }} + image: {{ .Config.GetVariableValue "IMAGENAME" }}:{{ .Config.GetVariableValue "IMAGETAG" }} imagePullPolicy: Always ports: - - containerPort: {{.PORT}} \ No newline at end of file + - containerPort: {{ .Config.GetVariableValue "PORT"}} \ No newline at end of file diff --git a/template/deployments/manifests/manifests/service.yaml b/template/deployments/manifests/manifests/service.yaml index 83481aa4..7503816d 100644 --- a/template/deployments/manifests/manifests/service.yaml +++ b/template/deployments/manifests/manifests/service.yaml @@ -1,15 +1,15 @@ apiVersion: v1 kind: Service metadata: - name: {{.APPNAME}} - namespace: {{.NAMESPACE}} + name: {{ .Config.GetVariableValue "APPNAME" }} + namespace: {{ .Config.GetVariableValue "NAMESPACE" }} labels: - kubernetes.azure.com/generator: {{.GENERATORLABEL}} + kubernetes.azure.com/generator: {{ .Config.GetVariableValue "GENERATORLABEL" }} spec: type: LoadBalancer selector: - app: {{.APPNAME}} + app: {{ .Config.GetVariableValue "APPNAME" }} ports: - protocol: TCP - port: {{.SERVICEPORT}} - targetPort: {{.PORT}} \ No newline at end of file + port: {{ .Config.GetVariableValue "SERVICEPORT" }} + targetPort: {{ .Config.GetVariableValue "PORT" }} \ No newline at end of file diff --git a/template/dockerfiles.go b/template/dockerfiles.go deleted file mode 100644 index 9fefca7d..00000000 --- a/template/dockerfiles.go +++ /dev/null @@ -1,8 +0,0 @@ -package template - -import "embed" - -var ( - //go:embed all:dockerfiles - Dockerfiles embed.FS -) diff --git a/template/dockerfiles/clojure/.dockerignore b/template/dockerfiles/clojure/.dockerignore index 5b48e5e8..310cd0c8 100644 --- a/template/dockerfiles/clojure/.dockerignore +++ b/template/dockerfiles/clojure/.dockerignore @@ -1,4 +1,4 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ resources/ target/ diff --git a/template/dockerfiles/clojure/Dockerfile b/template/dockerfiles/clojure/Dockerfile index 76957ddc..386a133b 100644 --- a/template/dockerfiles/clojure/Dockerfile +++ b/template/dockerfiles/clojure/Dockerfile @@ -3,11 +3,11 @@ COPY . /usr/src/app WORKDIR /usr/src/app RUN lein ring uberjar -FROM eclipse-temurin:{{.VERSION}} +FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} RUN apk update && apk upgrade && apk add bash -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT"}} COPY --from=BUILD /usr/src/app/target/*.jar /opt/ WORKDIR /opt CMD ["/bin/bash", "-c", "find -type f -name '*standalone.jar' | xargs java -jar"] diff --git a/template/dockerfiles/clojure/draft.yaml b/template/dockerfiles/clojure/draft.yaml index bbe7a1e9..1ccbff76 100644 --- a/template/dockerfiles/clojure/draft.yaml +++ b/template/dockerfiles/clojure/draft.yaml @@ -2,6 +2,8 @@ language: clojure displayName: Clojure templateName: "dockerfile-clojure" description: "This template is used to create a Dockerfile for a Clojure application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -18,3 +21,12 @@ variables: description: "the version of openjdk that the application uses" exampleValues: ["8-jdk-alpine", "11-jdk-alpine", "17-jdk-alpine", "19-jdk-alpine"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" diff --git a/template/dockerfiles/csharp/.dockerignore b/template/dockerfiles/csharp/.dockerignore index ac690088..7a0a9dfa 100644 --- a/template/dockerfiles/csharp/.dockerignore +++ b/template/dockerfiles/csharp/.dockerignore @@ -1,4 +1,4 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ bin/ obj/ diff --git a/template/dockerfiles/csharp/Dockerfile b/template/dockerfiles/csharp/Dockerfile index 992ad424..e8e411cc 100644 --- a/template/dockerfiles/csharp/Dockerfile +++ b/template/dockerfiles/csharp/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:{{.VERSION}} AS builder +FROM mcr.microsoft.com/dotnet/sdk:{{ .Config.GetVariableValue "VERSION" }} AS builder WORKDIR /app # caches restore result by copying csproj file separately @@ -11,11 +11,11 @@ RUN sed -n 's:.*\(.*\).*:\1:p' *.csproj > __assembl RUN if [ ! -s __assemblyname ]; then filename=$(ls *.csproj); echo ${filename%.*} > __assemblyname; fi # Stage 2 -FROM mcr.microsoft.com/dotnet/aspnet:{{.VERSION}} +FROM mcr.microsoft.com/dotnet/aspnet:{{ .Config.GetVariableValue "VERSION" }} WORKDIR /app COPY --from=builder /app . -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} -ENTRYPOINT dotnet $(cat /app/__assemblyname).dll --urls "http://*:{{.PORT}}" +ENTRYPOINT dotnet $(cat /app/__assemblyname).dll --urls "http://*:{{ .Config.GetVariableValue "PORT" }}" diff --git a/template/dockerfiles/csharp/draft.yaml b/template/dockerfiles/csharp/draft.yaml index 4c15c0f2..7fcbe52c 100644 --- a/template/dockerfiles/csharp/draft.yaml +++ b/template/dockerfiles/csharp/draft.yaml @@ -2,6 +2,8 @@ language: csharp displayName: C# templateName: "dockerfile-csharp" description: "This template is used to create a Dockerfile for a C# application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "float" kind: "containerImageVersion" @@ -17,3 +20,12 @@ variables: value: "5.0" description: "the dotnet SDK version" exampleValues: ["3.1", "4.0", "5.0", "6.0"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" diff --git a/template/dockerfiles/erlang/.dockerignore b/template/dockerfiles/erlang/.dockerignore index 1822f8ce..b5851667 100644 --- a/template/dockerfiles/erlang/.dockerignore +++ b/template/dockerfiles/erlang/.dockerignore @@ -1,2 +1,3 @@ # files and directories to exclude from context +{{ .Config.GetVariableValue "DOCKERFILENAME" }} _build \ No newline at end of file diff --git a/template/dockerfiles/erlang/Dockerfile b/template/dockerfiles/erlang/Dockerfile index 2245dfe5..5d176e90 100644 --- a/template/dockerfiles/erlang/Dockerfile +++ b/template/dockerfiles/erlang/Dockerfile @@ -1,4 +1,4 @@ -FROM erlang:{{.BUILDERVERSION}} as builder +FROM erlang:{{ .Config.GetVariableValue "BUILDERVERSION" }} as builder RUN apk add --update tar curl git bash make libc-dev gcc g++ && \ rm -rf /var/cache/apk/* @@ -20,18 +20,18 @@ RUN tar -zxvf /usr/src/app/_build/prod/rel/*/*.tar.gz -C /opt/rel RUN relname=$(ls _build/prod/rel) ; echo $relname > /opt/rel/__relname -FROM alpine:{{.VERSION}} +FROM alpine:{{ .Config.GetVariableValue "VERSION" }} RUN apk add --no-cache openssl-dev ncurses libstdc++ libgcc WORKDIR /opt/rel ENV RELX_REPLACE_OS_VARS true -ENV HTTP_PORT {{.PORT}} +ENV HTTP_PORT {{ .Config.GetVariableValue "PORT" }} COPY --from=builder /opt/rel /opt/rel -EXPOSE {{.PORT}} {{.PORT}} +EXPOSE {{ .Config.GetVariableValue "PORT" }} {{ .Config.GetVariableValue "PORT" }} RUN ln -s /opt/rel/bin/$(cat /opt/rel/__relname) /opt/rel/bin/start_script ENTRYPOINT ["/opt/rel/bin/start_script"] diff --git a/template/dockerfiles/erlang/draft.yaml b/template/dockerfiles/erlang/draft.yaml index 9d7caf6f..e456c522 100644 --- a/template/dockerfiles/erlang/draft.yaml +++ b/template/dockerfiles/erlang/draft.yaml @@ -2,6 +2,8 @@ language: erlang displayName: Erlang templateName: "dockerfile-erlang" description: "This template is used to create a Dockerfile for an Erlang application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "BUILDERVERSION" type: "string" kind: "containerImageVersion" @@ -17,6 +20,7 @@ variables: value: "27.0-alpine" description: "the version of erlang used during the builder stage to generate the executable" exampleValues: ["27.0-alpine"] + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -24,3 +28,12 @@ variables: value: "3.17" description: "the version of alpine used by the application" exampleValues: ["3.17"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/go/.dockerignore b/template/dockerfiles/go/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/go/.dockerignore +++ b/template/dockerfiles/go/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/go/Dockerfile b/template/dockerfiles/go/Dockerfile index aa359511..564b27ed 100644 --- a/template/dockerfiles/go/Dockerfile +++ b/template/dockerfiles/go/Dockerfile @@ -1,6 +1,6 @@ -FROM golang:{{.VERSION}} -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM golang:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT={{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} WORKDIR /go/src/app COPY . . diff --git a/template/dockerfiles/go/draft.yaml b/template/dockerfiles/go/draft.yaml index 0523c3e0..999f8c59 100644 --- a/template/dockerfiles/go/draft.yaml +++ b/template/dockerfiles/go/draft.yaml @@ -2,6 +2,8 @@ language: go displayName: Go templateName: "dockerfile-go" description: "This template is used to create a Dockerfile for a Go application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,10 +12,20 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" default: - value: "1.18" + value: "1.23" description: "the version of go used by the application" - exampleValues: ["1.16", "1.17", "1.18", "1.19"] + exampleValues: ["1.20", "1.21", "1.22", "1.23"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/gomodule/.dockerignore b/template/dockerfiles/gomodule/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/gomodule/.dockerignore +++ b/template/dockerfiles/gomodule/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/gomodule/Dockerfile b/template/dockerfiles/gomodule/Dockerfile index 57c1f48e..2e11be4d 100644 --- a/template/dockerfiles/gomodule/Dockerfile +++ b/template/dockerfiles/gomodule/Dockerfile @@ -1,6 +1,4 @@ -FROM golang:{{.VERSION}} AS builder -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM golang:{{ .Config.GetVariableValue "VERSION" }} AS builder WORKDIR /build COPY go.mod go.sum ./ @@ -9,6 +7,10 @@ COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -v -o app-binary FROM gcr.io/distroless/static-debian12 + +ENV PORT={{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} + WORKDIR /app COPY --from=builder /build/app-binary . CMD ["/app/app-binary"] diff --git a/template/dockerfiles/gomodule/draft.yaml b/template/dockerfiles/gomodule/draft.yaml index 0978b0d3..c4d6d316 100644 --- a/template/dockerfiles/gomodule/draft.yaml +++ b/template/dockerfiles/gomodule/draft.yaml @@ -2,6 +2,8 @@ language: gomodule displayName: Go Module templateName: "dockerfile-gomodule" description: "This template is used to create a Dockerfile for a Go Module application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,10 +12,20 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" default: - value: "1.18" + value: "1.23" description: "the version of go used by the application" - exampleValues: ["1.16", "1.17", "1.18", "1.19"] + exampleValues: ["1.20", "1.21", "1.22", "1.23"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/gradle/.dockerignore b/template/dockerfiles/gradle/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/gradle/.dockerignore +++ b/template/dockerfiles/gradle/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/gradle/Dockerfile b/template/dockerfiles/gradle/Dockerfile index 79d9acca..b7bc9613 100644 --- a/template/dockerfiles/gradle/Dockerfile +++ b/template/dockerfiles/gradle/Dockerfile @@ -1,11 +1,11 @@ -FROM gradle:{{.BUILDERVERSION}} as BUILD +FROM gradle:{{ .Config.GetVariableValue "BUILDERVERSION" }} as BUILD COPY --chown=gradle:gradle . /project RUN gradle -i -s -b /project/build.gradle clean build -FROM eclipse-temurin:{{.VERSION}} -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} COPY --from=BUILD /project/build/libs/* /opt/ WORKDIR /opt/ diff --git a/template/dockerfiles/gradle/draft.yaml b/template/dockerfiles/gradle/draft.yaml index 182c5117..cff58e9f 100644 --- a/template/dockerfiles/gradle/draft.yaml +++ b/template/dockerfiles/gradle/draft.yaml @@ -2,6 +2,8 @@ language: gradle displayName: Gradle templateName: "dockerfile-gradle" description: "This template is used to create a Dockerfile for a Gradle application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "BUILDERVERSION" type: "string" kind: "containerImageVersion" @@ -17,6 +20,7 @@ variables: value: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8", "jdk11", "jdk17", "jdk19", "jdk21"] + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -24,3 +28,12 @@ variables: value: "21-jre" description: "the java version used by the application" exampleValues: ["11-jre", "17-jre", "19-jre", "21-jre"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/gradlew/.dockerignore b/template/dockerfiles/gradlew/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/gradlew/.dockerignore +++ b/template/dockerfiles/gradlew/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/gradlew/Dockerfile b/template/dockerfiles/gradlew/Dockerfile index 0a09d128..f9ca9026 100644 --- a/template/dockerfiles/gradlew/Dockerfile +++ b/template/dockerfiles/gradlew/Dockerfile @@ -1,4 +1,4 @@ -FROM gradle:{{.BUILDERVERSION}} as BUILD +FROM gradle:{{ .Config.GetVariableValue "BUILDERVERSION" }} as BUILD COPY --chown=gradle:gradle . /project COPY gradlew gradlew @@ -7,9 +7,9 @@ RUN chmod +x gradle/wrapper RUN chmod +x gradlew RUN ./gradlew -i -s -b /project/build.gradle clean build -FROM eclipse-temurin:{{.VERSION}} -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} COPY --from=BUILD /project/build/libs/* /opt/ WORKDIR /opt/ diff --git a/template/dockerfiles/gradlew/draft.yaml b/template/dockerfiles/gradlew/draft.yaml index 182c5117..0b9ca9c4 100644 --- a/template/dockerfiles/gradlew/draft.yaml +++ b/template/dockerfiles/gradlew/draft.yaml @@ -1,7 +1,9 @@ language: gradle displayName: Gradle -templateName: "dockerfile-gradle" +templateName: "dockerfile-gradlew" description: "This template is used to create a Dockerfile for a Gradle application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "BUILDERVERSION" type: "string" kind: "containerImageVersion" @@ -17,6 +20,7 @@ variables: value: "jdk21" description: "the version of gradle used during the builder stage to generate the executable" exampleValues: ["jdk8", "jdk11", "jdk17", "jdk19", "jdk21"] + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -24,3 +28,12 @@ variables: value: "21-jre" description: "the java version used by the application" exampleValues: ["11-jre", "17-jre", "19-jre", "21-jre"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/java/.dockerignore b/template/dockerfiles/java/.dockerignore index c81336fd..2f7bbf2a 100644 --- a/template/dockerfiles/java/.dockerignore +++ b/template/dockerfiles/java/.dockerignore @@ -1,4 +1,4 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ target/ work/ diff --git a/template/dockerfiles/java/Dockerfile b/template/dockerfiles/java/Dockerfile index 5ab34fdc..baa33d52 100644 --- a/template/dockerfiles/java/Dockerfile +++ b/template/dockerfiles/java/Dockerfile @@ -1,11 +1,11 @@ -FROM maven:{{.BUILDERVERSION}} as BUILD +FROM maven:{{ .Config.GetVariableValue "BUILDERVERSION" }} as BUILD COPY . /usr/src/app RUN mvn --batch-mode -f /usr/src/app/pom.xml clean package -FROM eclipse-temurin:{{.VERSION}} -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM eclipse-temurin:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} COPY --from=BUILD /usr/src/app/target /opt/target WORKDIR /opt/target diff --git a/template/dockerfiles/java/draft.yaml b/template/dockerfiles/java/draft.yaml index 7cbf81e4..59a825ec 100644 --- a/template/dockerfiles/java/draft.yaml +++ b/template/dockerfiles/java/draft.yaml @@ -2,6 +2,8 @@ language: java displayName: Java templateName: "dockerfile-java" description: "This template is used to create a Dockerfile for a Java application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "BUILDERVERSION" type: "string" kind: "containerImageVersion" @@ -18,6 +21,7 @@ variables: description: "the version of maven used during the builder stage to generate the executable" exampleValues: ["3-eclipse-temurin-17", "3-eclipse-temurin-21", "3 (jdk-21)"] + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -25,3 +29,12 @@ variables: value: "21-jre" description: "the java version used by the application" exampleValues: ["11-jre", "17-jre", "19-jre", "21-jre"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/javascript/.dockerignore b/template/dockerfiles/javascript/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/javascript/.dockerignore +++ b/template/dockerfiles/javascript/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/javascript/Dockerfile b/template/dockerfiles/javascript/Dockerfile index 96c7c168..56abb05f 100644 --- a/template/dockerfiles/javascript/Dockerfile +++ b/template/dockerfiles/javascript/Dockerfile @@ -1,6 +1,6 @@ -FROM node:{{.VERSION}} -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM node:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} RUN mkdir -p /usr/src/app WORKDIR /usr/src/app diff --git a/template/dockerfiles/javascript/draft.yaml b/template/dockerfiles/javascript/draft.yaml index 701bdbc2..f3d8bbda 100644 --- a/template/dockerfiles/javascript/draft.yaml +++ b/template/dockerfiles/javascript/draft.yaml @@ -2,6 +2,8 @@ language: javascript displayName: JavaScript templateName: "dockerfile-javascript" description: "This template is used to create a Dockerfile for a JavaScript application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -17,3 +20,12 @@ variables: value: "14" description: "the version of node used in the application" exampleValues: ["10.16.3", "12.16.3", "14.15.4"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/php/.dockerignore b/template/dockerfiles/php/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/php/.dockerignore +++ b/template/dockerfiles/php/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/php/Dockerfile b/template/dockerfiles/php/Dockerfile index 00b7c9fe..8e3c2aff 100644 --- a/template/dockerfiles/php/Dockerfile +++ b/template/dockerfiles/php/Dockerfile @@ -1,10 +1,10 @@ -FROM composer:{{.BUILDERVERSION}} AS build-env +FROM composer:{{ .Config.GetVariableValue "BUILDERVERSION" }} AS build-env COPY . /app RUN cd /app && composer install -FROM php:{{.VERSION}} -ENV PORT 80 -EXPOSE 80 +FROM php:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} COPY --from=build-env /app /var/www/html RUN usermod -u 1000 www-data; \ a2enmod rewrite; \ diff --git a/template/dockerfiles/php/draft.yaml b/template/dockerfiles/php/draft.yaml index 1ca077c7..6f71621b 100644 --- a/template/dockerfiles/php/draft.yaml +++ b/template/dockerfiles/php/draft.yaml @@ -2,6 +2,8 @@ language: php displayName: PHP templateName: "dockerfile-php" description: "This template is used to create a Dockerfile for a PHP application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "BUILDERVERSION" type: "string" kind: "containerImageVersion" @@ -17,6 +20,7 @@ variables: value: "1" description: "the version of composer installed during the build stage to be used by the application" exampleValues: ["1"] + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -24,3 +28,12 @@ variables: value: "7.1-apache" description: "the version of php used by the application" exampleValues: ["7.1-apache"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/python/.dockerignore b/template/dockerfiles/python/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/python/.dockerignore +++ b/template/dockerfiles/python/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/python/Dockerfile b/template/dockerfiles/python/Dockerfile index 87e0aa67..f21016e0 100644 --- a/template/dockerfiles/python/Dockerfile +++ b/template/dockerfiles/python/Dockerfile @@ -1,6 +1,6 @@ -FROM python:{{.VERSION}} -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM python:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} WORKDIR /usr/src/app COPY requirements.txt ./ @@ -9,4 +9,4 @@ RUN pip install --no-cache-dir -r requirements.txt COPY . . ENTRYPOINT ["python"] -CMD ["{{.ENTRYPOINT}}"] \ No newline at end of file +CMD ["{{ .Config.GetVariableValue "ENTRYPOINT" }}"] \ No newline at end of file diff --git a/template/dockerfiles/python/draft.yaml b/template/dockerfiles/python/draft.yaml index 7250eb07..809c8324 100644 --- a/template/dockerfiles/python/draft.yaml +++ b/template/dockerfiles/python/draft.yaml @@ -2,6 +2,8 @@ language: python displayName: Python templateName: "dockerfile-python" description: "This template is used to create a Dockerfile for a Python application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -17,6 +20,7 @@ variables: value: "3" description: "the version of python used by the application" exampleValues: ["3.9", "3.8", "3.7", "3.6"] + versions: ">=0.0.1" - name: "ENTRYPOINT" type: "string" kind: "filePath" @@ -24,3 +28,12 @@ variables: value: "app.py" description: "the entrypoint file of the repository" exampleValues: ["app.py", "main.py"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/ruby/.dockerignore b/template/dockerfiles/ruby/.dockerignore index 3e5a44ea..e5badce4 100644 --- a/template/dockerfiles/ruby/.dockerignore +++ b/template/dockerfiles/ruby/.dockerignore @@ -1,3 +1,3 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ tmp/ diff --git a/template/dockerfiles/ruby/Dockerfile b/template/dockerfiles/ruby/Dockerfile index 5ffdc260..52487c7d 100644 --- a/template/dockerfiles/ruby/Dockerfile +++ b/template/dockerfiles/ruby/Dockerfile @@ -1,6 +1,6 @@ -FROM ruby:{{.VERSION}} -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +FROM ruby:{{ .Config.GetVariableValue "VERSION" }} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} RUN bundle config --global frozen 1 WORKDIR /usr/src/app diff --git a/template/dockerfiles/ruby/draft.yaml b/template/dockerfiles/ruby/draft.yaml index 99d64b99..1a64243f 100644 --- a/template/dockerfiles/ruby/draft.yaml +++ b/template/dockerfiles/ruby/draft.yaml @@ -2,6 +2,8 @@ language: ruby displayName: Ruby templateName: "dockerfile-ruby" description: "This template is used to create a Dockerfile for a Ruby application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -17,3 +20,12 @@ variables: value: "3.1.2" description: "the version of ruby used by the application" exampleValues: ["3.1.2", "2.6", "2.5", "2.4"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/rust/.dockerignore b/template/dockerfiles/rust/.dockerignore index 160b0d8e..bcace91b 100644 --- a/template/dockerfiles/rust/.dockerignore +++ b/template/dockerfiles/rust/.dockerignore @@ -1,3 +1,3 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ target diff --git a/template/dockerfiles/rust/Dockerfile b/template/dockerfiles/rust/Dockerfile index 86827ea2..d02d96ce 100644 --- a/template/dockerfiles/rust/Dockerfile +++ b/template/dockerfiles/rust/Dockerfile @@ -1,10 +1,10 @@ -FROM rust:{{.VERSION}} +FROM rust:{{ .Config.GetVariableValue "VERSION" }} WORKDIR /usr/src/app COPY . /usr/src/app RUN cargo build -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} CMD ["cargo", "run", "-q"] diff --git a/template/dockerfiles/rust/draft.yaml b/template/dockerfiles/rust/draft.yaml index 284cba73..22a7d218 100644 --- a/template/dockerfiles/rust/draft.yaml +++ b/template/dockerfiles/rust/draft.yaml @@ -2,6 +2,8 @@ language: rust displayName: Rust templateName: "dockerfile-rust" description: "This template is used to create a Dockerfile for a Rust application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -17,3 +20,12 @@ variables: 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"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/dockerfiles/swift/.dockerignore b/template/dockerfiles/swift/.dockerignore index 843dec4f..868566d2 100644 --- a/template/dockerfiles/swift/.dockerignore +++ b/template/dockerfiles/swift/.dockerignore @@ -1,2 +1,2 @@ -Dockerfile +{{ .Config.GetVariableValue "DOCKERFILENAME" }} charts/ diff --git a/template/dockerfiles/swift/Dockerfile b/template/dockerfiles/swift/Dockerfile index 68594e78..d83bf7bf 100644 --- a/template/dockerfiles/swift/Dockerfile +++ b/template/dockerfiles/swift/Dockerfile @@ -1,11 +1,11 @@ -FROM swift:{{.VERSION}} +FROM swift:{{ .Config.GetVariableValue "VERSION" }} WORKDIR /src COPY . /src RUN apt-get update && apt-get install -y sudo openssl libssl-dev libcurl4-openssl-dev RUN swift build -c release -ENV PORT {{.PORT}} -EXPOSE {{.PORT}} +ENV PORT {{ .Config.GetVariableValue "PORT" }} +EXPOSE {{ .Config.GetVariableValue "PORT" }} CMD ["swift", "run"] diff --git a/template/dockerfiles/swift/draft.yaml b/template/dockerfiles/swift/draft.yaml index 186d8ffe..caf72f3c 100644 --- a/template/dockerfiles/swift/draft.yaml +++ b/template/dockerfiles/swift/draft.yaml @@ -2,6 +2,8 @@ language: swift displayName: Swift templateName: "dockerfile-swift" description: "This template is used to create a Dockerfile for a Swift application" +versions: "0.0.1" +defaultVersion: "0.0.1" type: "dockerfile" variables: - name: "PORT" @@ -10,6 +12,7 @@ variables: default: value: "80" description: "the port exposed in the application" + versions: ">=0.0.1" - name: "VERSION" type: "string" kind: "containerImageVersion" @@ -17,3 +20,12 @@ variables: value: "5.5" description: "the version of swift used by the application" exampleValues: ["5.2", "5.5"] + versions: ">=0.0.1" + - name: "DOCKERFILENAME" + type: "string" + kind: "dockerFileName" + default: + value: "Dockerfile" + disablePrompt: true + description: "the name of the Dockerfile" + versions: ">=0.0.1" \ No newline at end of file diff --git a/template/manifests/HorizontalPodAutoscaling/manifest/draft.yaml b/template/manifests/HorizontalPodAutoscaling/manifest/draft.yaml new file mode 100644 index 00000000..85aa7fb0 --- /dev/null +++ b/template/manifests/HorizontalPodAutoscaling/manifest/draft.yaml @@ -0,0 +1,42 @@ +templateName: "horizontalPodAutoscaling-manifest" +description: "This template is used to create a horizontalPodAutoscaling for an application" +type: "manifest" +variables: + - name: "APPNAME" + type: "string" + kind: "kubernetesResourceName" + description: "the name of the application" + - name: "PARTOF" + type: "string" + kind: "label" + description: "the label to identify which project the resource belong to" + - name: "GENERATORLABEL" + type: "string" + kind: "label" + description: "the label to identify who generated the resource" + default: + value: "draft" + - name: "MINIMUMREPLICAS" + type: "int" + kind: "replicaCount" + description: "specifies the minimum number of pod replicas that the deployment should have" + default: + value: 2 + - name: "MAXIMUMREPLICAS" + type: "int" + kind: "replicaCount" + description: "defines the maximum number of pod replicas the deployment can scale to" + default: + value: 5 + - name: "RESOURCETYPE" + type: "string" + kind: "scalingResourceType" + description: "specifies the resource type (e.g., cpu or memory) to be monitored for scaling" + default: + value: "cpu" + - name: "AVGUTILIZATION" + type: "int" + kind: "scalingResourceUtilization" + description: "specifies the average utilization for the monitored resource, triggering scaling when exceeded" + default: + value: 80 \ No newline at end of file diff --git a/template/manifests/HorizontalPodAutoscaling/manifest/hpa.yaml b/template/manifests/HorizontalPodAutoscaling/manifest/hpa.yaml new file mode 100644 index 00000000..3250dd6e --- /dev/null +++ b/template/manifests/HorizontalPodAutoscaling/manifest/hpa.yaml @@ -0,0 +1,22 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{.APPNAME}} + labels: + app.kubernetes.io/name: {{.APPNAME}} + app.kubernetes.io/part-of: {{.PARTOF}} + kubernetes.azure.com/generator: {{.GENERATORLABEL}} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{.APPNAME}} + minReplicas: {{.MINIMUMREPLICAS}} + maxReplicas: {{.MAXIMUMREPLICAS}} + metrics: + - type: Resource + resource: + name: {{.RESOURCETYPE}} + target: + type: Utilization + averageUtilization: {{.AVGUTILIZATION}} \ No newline at end of file diff --git a/template/manifests/PodDisruptionBudget/manifest/draft.yaml b/template/manifests/PodDisruptionBudget/manifest/draft.yaml new file mode 100644 index 00000000..58bc20fa --- /dev/null +++ b/template/manifests/PodDisruptionBudget/manifest/draft.yaml @@ -0,0 +1,24 @@ +templateName: "podDisruptionBudget-manifest" +description: "This template is used to create a PodDisruptionBudget for an application" +type: "manifest" +variables: + - name: "APPNAME" + type: "string" + kind: "kubernetesResourceName" + description: "the name of the application" + - name: "PARTOF" + type: "string" + kind: "label" + description: "the label to identify which project the resource belong to" + - name: "GENERATORLABEL" + type: "string" + kind: "label" + description: "the label to identify who generated the resource" + default: + value: "draft" + - name: "MAXUNAVAILABLE" + type: "int" + kind: "resourceLimit" + description: "specifies the maximum number of pods that can be unavailable during a disruption, such as a pod eviction" + default: + value: 1 \ No newline at end of file diff --git a/template/manifests/PodDisruptionBudget/manifest/pdb.yaml b/template/manifests/PodDisruptionBudget/manifest/pdb.yaml new file mode 100644 index 00000000..71f25c83 --- /dev/null +++ b/template/manifests/PodDisruptionBudget/manifest/pdb.yaml @@ -0,0 +1,13 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{.APPNAME}} + labels: + app.kubernetes.io/name: {{.APPNAME}} + app.kubernetes.io/part-of: {{.PARTOF}} + kubernetes.azure.com/generator: {{.GENERATORLABEL}} +spec: + maxUnavailable: {{.MAXUNAVAILABLE}} + selector: + matchLabels: + app: {{.APPNAME}} \ No newline at end of file From 2b42fb2338c834964a3ad0a965f8bdad6aad28ec Mon Sep 17 00:00:00 2001 From: Vidya Reddy <59590642+Vidya2606@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:16:13 -0700 Subject: [PATCH 2/2] updating the dependencies --- go.sum | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go.sum b/go.sum index 4438cbb2..2c32cd87 100644 --- a/go.sum +++ b/go.sum @@ -509,6 +509,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -544,6 +546,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=