diff --git a/.github/workflows/check-links-quickly.yaml b/.github/workflows/check-links-quickly.yaml index fa666b08..0ae3557b 100644 --- a/.github/workflows/check-links-quickly.yaml +++ b/.github/workflows/check-links-quickly.yaml @@ -17,24 +17,24 @@ jobs: linkChecker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Restore lychee cache id: restore-cache - uses: actions/cache/restore@v4 + uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4 with: path: .lycheecache key: cache-lychee-${{ github.sha }} restore-keys: cache-lychee- - name: Run lychee - uses: lycheeverse/lychee-action@v1.10.0 + uses: lycheeverse/lychee-action@f796c8b7d468feb9b8c0a46da3fac0af6874d374 # v2.2.0 with: fail: true args: "--base . --verbose --no-progress --cache --max-cache-age 3d 'docs/**/*.md'" - name: Save lychee cache - uses: actions/cache/save@v4 + uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4 if: always() with: path: .lycheecache diff --git a/.github/workflows/check-links.yaml b/.github/workflows/check-links.yaml index 530d83b9..967c7b4f 100644 --- a/.github/workflows/check-links.yaml +++ b/.github/workflows/check-links.yaml @@ -13,23 +13,23 @@ jobs: linkChecker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Restore lychee cache id: restore-cache - uses: actions/cache/restore@v4 + uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4 with: path: .lycheecache key: cache-lychee-${{ github.sha }} restore-keys: cache-lychee- - name: Run lychee - uses: lycheeverse/lychee-action@v1.10.0 + uses: lycheeverse/lychee-action@f796c8b7d468feb9b8c0a46da3fac0af6874d374 # v2.2.0 with: args: "--base . --verbose --no-progress --cache --max-cache-age 3d 'docs/**/*.md'" - name: Save lychee cache - uses: actions/cache/save@v4 + uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4 if: always() with: path: .lycheecache @@ -37,7 +37,7 @@ jobs: - name: Create Issue From File if: env.lychee_exit_code != 0 - uses: peter-evans/create-issue-from-file@v5 + uses: peter-evans/create-issue-from-file@e8ef132d6df98ed982188e460ebb3b5d4ef3a9cd # v5 with: title: Link Checker Report content-filepath: ./lychee/out.md diff --git a/.github/workflows/flow-pr-meta.yml b/.github/workflows/flow-pr-meta.yml index aff31dc9..0b4e7584 100644 --- a/.github/workflows/flow-pr-meta.yml +++ b/.github/workflows/flow-pr-meta.yml @@ -15,12 +15,12 @@ jobs: validate-title: runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v5 + - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5 id: lint_pr_title env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: marocchino/sticky-pull-request-comment@v2 + - uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2 # When the previous steps fails, the workflow would stop. By adding this # condition you can continue the execution with the populated error message. if: always() && (steps.lint_pr_title.outputs.error_message != null) @@ -39,7 +39,7 @@ jobs: # Delete a previous comment when the issue has been resolved - if: ${{ steps.lint_pr_title.outputs.error_message == null }} - uses: marocchino/sticky-pull-request-comment@v2 + uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2 with: header: pr-title-lint-error delete: true diff --git a/.github/workflows/job-lint.yml b/.github/workflows/job-lint.yml index efc24edc..9edbc136 100644 --- a/.github/workflows/job-lint.yml +++ b/.github/workflows/job-lint.yml @@ -1,4 +1,4 @@ -name: "job-lint" +name: 'job-lint' on: workflow_call: @@ -8,12 +8,15 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v5 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 with: - go-version: "1.22" cache: false + go-version-file: go.mod - name: Install gofumpt - uses: jaxxstorm/action-install-gh-release@v1.12.0 + uses: jaxxstorm/action-install-gh-release@cd6b2b78ad38bdd294341cda064ec0692b06215b # v1.14.0 with: repo: mvdan/gofumpt tag: v0.5.0 @@ -21,9 +24,6 @@ jobs: extension-matching: nah rename-to: gofumpt chmod: 0700 - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: Check code formatting run: | set -euo pipefail @@ -34,4 +34,4 @@ jobs: ) \ | tee /dev/stderr \ | test $(wc -l) -eq 0 - - uses: golangci/golangci-lint-action@v6 + - uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae # v6 diff --git a/.github/workflows/job-test.yml b/.github/workflows/job-test.yml index 940c16c1..bdec00d3 100644 --- a/.github/workflows/job-test.yml +++ b/.github/workflows/job-test.yml @@ -1,5 +1,5 @@ --- -name: "job-test" +name: 'job-test' on: workflow_call: @@ -9,25 +9,23 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 - - uses: actions/setup-go@v5 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 with: - go-version: "1.22" + go-version-file: go.mod - name: Build myks run: go install . - name: Test - run: - go test -failfast -race -coverpkg=./... -covermode=atomic - -coverprofile=coverage.txt ./... + run: go test -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt ./... - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: - file: ./coverage.txt - - uses: goreleaser/goreleaser-action@v6 + files: ./coverage.txt + - uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6 with: version: latest args: build --snapshot --clean diff --git a/.prettierrc.yaml b/.prettierrc.yaml index 1deb191f..5ae1ba99 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -1 +1,2 @@ proseWrap: always +singleQuote: true diff --git a/CHANGELOG.md b/CHANGELOG.md index dedfd807..52691229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,71 @@ # Changelog +## [4.4.0](https://github.com/mykso/myks/compare/v4.3.2...v4.4.0) (2025-01-28) + + +### Features + +* add argocd.project.enabled option ([753ad11](https://github.com/mykso/myks/commit/753ad1112e9331cec7ae2b976a01f10a86add058)) + + +### Bug Fixes + +* skip creation of empty ArgoCD environment file ([dfcb78b](https://github.com/mykso/myks/commit/dfcb78b7f87d475e94c02c4008b8da709402636d)) +* sort ArgoCD Application YAML ([600cfa9](https://github.com/mykso/myks/commit/600cfa9feda23c5455db799ff917a6a96e253d76)) +* use argocd.project.name if set ([8e0fabd](https://github.com/mykso/myks/commit/8e0fabd4b107af4cffa733fce9463cb6da34a7b9)) + +## [4.3.2](https://github.com/mykso/myks/compare/v4.3.1...v4.3.2) (2025-01-27) + + +### Bug Fixes + +* ensure buildDependencies is nullable ([#378](https://github.com/mykso/myks/issues/378)) ([4e65a3e](https://github.com/mykso/myks/commit/4e65a3ea59ec2429b18b0ae1434f514ae23c9f09)) + +## [4.3.1](https://github.com/mykso/myks/compare/v4.3.0...v4.3.1) (2025-01-23) + + +### Bug Fixes + +* **deps:** update module github.com/alecthomas/chroma/v2 to v2.15.0 ([#370](https://github.com/mykso/myks/issues/370)) ([1916955](https://github.com/mykso/myks/commit/19169557ed40f7dc561dbd52db5d518b7e4a4d01)) +* **deps:** update module golang.org/x/term to v0.28.0 ([#368](https://github.com/mykso/myks/issues/368)) ([cb36943](https://github.com/mykso/myks/commit/cb369437cf77cf4bb939a72115fa79e4c9e7e247)) +* make per-chart helm options nullable ([#374](https://github.com/mykso/myks/issues/374)) ([4fd9713](https://github.com/mykso/myks/commit/4fd9713374519dec6593808b325480b4e7655dff)) + +## [4.3.0](https://github.com/mykso/myks/compare/v4.2.6...v4.3.0) (2025-01-01) + + +### Features + +* allow multiple files for app and env-data on each level ([#366](https://github.com/mykso/myks/issues/366)) ([3b2f68f](https://github.com/mykso/myks/commit/3b2f68f382a32c18297dc9b612f21a2a4c6cb250)) + +## [4.2.6](https://github.com/mykso/myks/compare/v4.2.5...v4.2.6) (2024-12-27) + + +### Bug Fixes + +* **deps:** update module carvel.dev/ytt to v0.51.1 ([#358](https://github.com/mykso/myks/issues/358)) ([e339a90](https://github.com/mykso/myks/commit/e339a90bf6fb0f38b883d44cfd9515e206f31926)) +* **docs:** overhaul help messages ([#362](https://github.com/mykso/myks/issues/362)) ([aa1f941](https://github.com/mykso/myks/commit/aa1f941d13dc341ec5f58c6e1f1a7cc684ff3a6e)) +* skip ArgoCD Application plugin if not set ([#365](https://github.com/mykso/myks/issues/365)) ([302667e](https://github.com/mykso/myks/commit/302667e607d5b7730b1dd28d5aca2cd584de53a8)) + +## [4.2.5](https://github.com/mykso/myks/compare/v4.2.4...v4.2.5) (2024-12-10) + + +### Bug Fixes + +* **deps:** update module carvel.dev/vendir to v0.43.0 ([#357](https://github.com/mykso/myks/issues/357)) ([ebf51cd](https://github.com/mykso/myks/commit/ebf51cdc5ed433a3440e0c8082648e7295a198a6)) +* **deps:** update module github.com/stretchr/testify to v1.10.0 ([#351](https://github.com/mykso/myks/issues/351)) ([a47b2ed](https://github.com/mykso/myks/commit/a47b2ed3fa1d77d49153a47246c5e09704919514)) +* **deps:** update module golang.org/x/sync to v0.10.0 ([#354](https://github.com/mykso/myks/issues/354)) ([7ed5e20](https://github.com/mykso/myks/commit/7ed5e20a8f01ba373ccd70c6761f4d77a9d1cd1a)) +* **deps:** update module golang.org/x/sync to v0.9.0 ([#345](https://github.com/mykso/myks/issues/345)) ([3abe265](https://github.com/mykso/myks/commit/3abe2650a586f83dc5417f7a63107bf0dee10743)) +* **deps:** update module golang.org/x/term to v0.26.0 ([#346](https://github.com/mykso/myks/issues/346)) ([edd9944](https://github.com/mykso/myks/commit/edd994416da29ba288dbf79a788aff2c6f317cae)) +* **deps:** update module golang.org/x/term to v0.27.0 ([#355](https://github.com/mykso/myks/issues/355)) ([78fe9b1](https://github.com/mykso/myks/commit/78fe9b1cb6dd17004e54cbfd81ee19fa42337fdb)) + +## [4.2.4](https://github.com/mykso/myks/compare/v4.2.3...v4.2.4) (2024-11-07) + + +### Bug Fixes + +* **deps:** update module carvel.dev/ytt to v0.51.0 ([#342](https://github.com/mykso/myks/issues/342)) ([836e1fd](https://github.com/mykso/myks/commit/836e1fda537aefb1d66a7e0c3e5146529df9d09a)) +* **deps:** update module golang.org/x/term to v0.25.0 ([#338](https://github.com/mykso/myks/issues/338)) ([b94de99](https://github.com/mykso/myks/commit/b94de998a349113a66feab8793ea8906d9449374)) + ## [4.2.3](https://github.com/mykso/myks/compare/v4.2.2...v4.2.3) (2024-09-11) diff --git a/Dockerfile b/Dockerfile index 4b599694..e4022f46 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ FROM downloader AS helm ARG TARGETOS ARG TARGETARCH # renovate: datasource=github-releases depName=helm/helm -ARG HELM_VERSION=v3.16.1 +ARG HELM_VERSION=v3.17.0 RUN curl -fsSL \ https://get.helm.sh/helm-${HELM_VERSION}-${TARGETOS}-${TARGETARCH}.tar.gz \ | tar -xzf - --strip-components=1 ${TARGETOS}-${TARGETARCH}/helm diff --git a/cmd/all.go b/cmd/all.go index e30def3b..e0d98346 100644 --- a/cmd/all.go +++ b/cmd/all.go @@ -10,7 +10,8 @@ import ( var allCmd = &cobra.Command{ Use: "all", Short: "Run sync and render", - Long: "Run sync and render", + Long: "Run sync and render for specified environments and applications", + Args: cobra.RangeArgs(0, 2), Annotations: map[string]string{ ANNOTATION_SMART_MODE: ANNOTATION_TRUE, }, diff --git a/cmd/render.go b/cmd/render.go index 9dde34a0..57e1dd99 100644 --- a/cmd/render.go +++ b/cmd/render.go @@ -10,7 +10,7 @@ import ( var renderCmd = &cobra.Command{ Use: "render", Short: "Render manifests", - Long: "Render manifests", + Long: "Render manifests for specified environments and applications", Annotations: map[string]string{ ANNOTATION_SMART_MODE: ANNOTATION_TRUE, }, diff --git a/cmd/root.go b/cmd/root.go index 61bbc46b..3e965c6c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -27,38 +27,97 @@ var ( asyncLevel int ) +// Use this template for commands that accept environment and application arguments +const envAppCommandUsageTemplate = `Usage: + {{.CommandPath}} [environments [applications]] [flags] + +Arguments: + 0. When no arguments are provided, myks uses the Smart Mode to determine the environments and applications to process. + In Smart Mode, myks relies on git to only processes applications with changes. + + 1. environments (Optional) Comma-separated list of environments or ALL + ALL will process all environments + Examples: ALL + prod,stage,dev + prod/region1,stage/region1 + dev + + 2. applications (Optional) Comma-separated list of applications or ALL + ALL will process all applications + Example: app1,app2 or ALL + +{{if .HasAvailableFlags}}Flags: +{{.Flags.FlagUsages | trimTrailingWhitespaces}}{{end}} + +Examples: + # Process all apps in production and staging + {{.CommandPath}} prod,stage ALL + + # Process specific apps in all environments + {{.CommandPath}} ALL app1,app2 + + # Process specific apps in specific environments + {{.CommandPath}} prod,stage app1,app2 +` + func NewMyksCmd(version, commit, date string) *cobra.Command { cobra.OnInitialize(initLogger) zerolog.SetGlobalLevel(zerolog.InfoLevel) cmd := newRootCmd(version, commit, date) cmd.AddCommand(allCmd) cmd.AddCommand(renderCmd) + cmd.AddCommand(syncCmd) cmd.AddCommand(newCleanupCmd()) cmd.AddCommand(newInitCmd()) cmd.AddCommand(newPrintConfigCmd()) - cmd.AddCommand(newSyncCmd()) cmd.AddCommand(embedded.EmbeddedCmd("vendir", "Vendir is embedded in myks to manage vendir.yaml files.")) cmd.AddCommand(embedded.EmbeddedCmd("ytt", "Ytt is embedded in myks to manage yaml files.")) initConfig() addPlugins(cmd) + + allCmd.SetUsageTemplate(envAppCommandUsageTemplate) + renderCmd.SetUsageTemplate(envAppCommandUsageTemplate) + syncCmd.SetUsageTemplate(envAppCommandUsageTemplate) + return cmd } func newRootCmd(version, commit, date string) *cobra.Command { rootCmd := &cobra.Command{ Use: "myks", - Short: "Myks helps to manage configuration for kubernetes clusters", - Long: `Myks fetches K8s workloads from a variety of sources, e.g. Helm charts or Git Repositories. It renders their respective yaml files to the file system in a structure of environments and their applications. - - It supports prototype applications that can be shared between environments and inheritance of configuration from parent environments to their "children". - - Myks supports two positional arguments: - - - A comma-separated list of environments to render. If you provide "ALL", all environments will be rendered. - - A comma-separated list of applications to render. If you don't provide this argument or provide "ALL", all applications will be rendered. - - If you do not provide any positional arguments, myks will run in "Smart Mode". In Smart Mode, myks will only render environments and applications that have changed since the last run. - `, + Short: "Myks generates Kubernetes manifests", + // TODO: Launch the documentation website and add a link here + Long: ` +Myks - Kubernetes Manifest Generator + +OVERVIEW + Myks simplifies Kubernetes manifest management through a standardized toolset + and GitOps-ready conventions. + +CORE FEATURES + • External source management (via vendir) + • Helm chart rendering + • YAML templating and validation (via ytt) + • Idempotent output + • Automatic ArgoCD resource generation + • Environment-based configuration inheritance + • Intelligent change detection + +BASIC COMMANDS + init Create a new Myks project in the current directory + sync Download external dependencies + render Generate Kubernetes manifests + all Perform sync and render in one step + +GETTING STARTED + 1. Create a new project: myks init + 2. Download dependencies: myks sync + 3. Generate manifests: myks render + +LEARN MORE + • Use 'myks --help' for detailed information about a command + • Report issues at https://github.com/example/myks/issues +`, } rootCmd.Version = fmt.Sprintf(`%s diff --git a/cmd/sync.go b/cmd/sync.go index 4e1255b5..8f980df1 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -7,36 +7,32 @@ import ( "github.com/mykso/myks/internal/myks" ) -func newSyncCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "sync", - Short: "Sync vendir configs", - Long: `Sync vendir configs. This will run vendir sync for all applications. +var syncCmd = &cobra.Command{ + Use: "sync", + Short: "Download external sources", + Long: `Download external sources for specified environments and applications. Authentication against protected repositories is achieved with environment variables prefixed with "VENDIR_SECRET_". For example, if you reference a secret named "mycreds" in your vendir.yaml, you need to export the variables "VENDIR_SECRET_MYCREDS_USERNAME" and "VENDIR_SECRET_MYCREDS_PASSWORD" in your environment.`, - Annotations: map[string]string{ - ANNOTATION_SMART_MODE: ANNOTATION_TRUE, - }, - Run: func(cmd *cobra.Command, args []string) { - log.Info().Msg("Syncing vendir configs") - g := myks.New(".") - - if err := g.ValidateRootDir(); err != nil { - log.Fatal().Err(err).Msg("Root directory is not suitable for myks") - } - - if err := g.Init(asyncLevel, envAppMap); err != nil { - log.Fatal().Err(err).Msg("Unable to initialize myks's globe") - } - - if err := g.Sync(asyncLevel); err != nil { - log.Fatal().Err(err).Msg("Unable to sync vendir configs") - } - }, - ValidArgsFunction: shellCompletion, - } - - return cmd + Annotations: map[string]string{ + ANNOTATION_SMART_MODE: ANNOTATION_TRUE, + }, + Run: func(cmd *cobra.Command, args []string) { + log.Info().Msg("Syncing vendir configs") + g := myks.New(".") + + if err := g.ValidateRootDir(); err != nil { + log.Fatal().Err(err).Msg("Root directory is not suitable for myks") + } + + if err := g.Init(asyncLevel, envAppMap); err != nil { + log.Fatal().Err(err).Msg("Unable to initialize myks's globe") + } + + if err := g.Sync(asyncLevel); err != nil { + log.Fatal().Err(err).Msg("Unable to sync vendir configs") + } + }, + ValidArgsFunction: shellCompletion, } diff --git a/examples/default/rendered/argocd/mykso-dev/app-argocd.yaml b/examples/default/rendered/argocd/mykso-dev/app-argocd.yaml index 2236835b..1b25d7b9 100644 --- a/examples/default/rendered/argocd/mykso-dev/app-argocd.yaml +++ b/examples/default/rendered/argocd/mykso-dev/app-argocd.yaml @@ -1,18 +1,18 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: - name: app-mykso-dev-argocd - namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io annotations: - myks.dev/environment: mykso-dev app.kubernetes.io/source: git@github.com:mykso/myks.git + myks.dev/environment: mykso-dev + finalizers: + - resources-finalizer.argocd.argoproj.io + name: app-mykso-dev-argocd + namespace: system-argocd spec: - project: env-mykso-dev destination: name: mykso-dev namespace: argocd + project: env-mykso-dev source: path: examples/default/rendered/envs/mykso-dev/argocd plugin: @@ -24,5 +24,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/default/rendered/argocd/mykso-dev/app-goldpinger.yaml b/examples/default/rendered/argocd/mykso-dev/app-goldpinger.yaml index c6cb8d72..aa44d6a1 100644 --- a/examples/default/rendered/argocd/mykso-dev/app-goldpinger.yaml +++ b/examples/default/rendered/argocd/mykso-dev/app-goldpinger.yaml @@ -1,18 +1,18 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: - name: app-mykso-dev-goldpinger - namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io annotations: - myks.dev/environment: mykso-dev app.kubernetes.io/source: git@github.com:mykso/myks.git + myks.dev/environment: mykso-dev + finalizers: + - resources-finalizer.argocd.argoproj.io + name: app-mykso-dev-goldpinger + namespace: system-argocd spec: - project: env-mykso-dev destination: name: mykso-dev namespace: goldpinger + project: env-mykso-dev source: path: examples/default/rendered/envs/mykso-dev/goldpinger plugin: @@ -24,5 +24,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/default/rendered/argocd/mykso-dev/app-httpbingo.yaml b/examples/default/rendered/argocd/mykso-dev/app-httpbingo.yaml index f2d0f04f..2cf477d9 100644 --- a/examples/default/rendered/argocd/mykso-dev/app-httpbingo.yaml +++ b/examples/default/rendered/argocd/mykso-dev/app-httpbingo.yaml @@ -1,18 +1,18 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: - name: app-mykso-dev-httpbingo - namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io annotations: - myks.dev/environment: mykso-dev app.kubernetes.io/source: git@github.com:mykso/myks.git + myks.dev/environment: mykso-dev + finalizers: + - resources-finalizer.argocd.argoproj.io + name: app-mykso-dev-httpbingo + namespace: system-argocd spec: - project: env-mykso-dev destination: name: mykso-dev namespace: httpbingo + project: env-mykso-dev source: path: examples/default/rendered/envs/mykso-dev/httpbingo plugin: @@ -24,5 +24,5 @@ spec: prune: true selfHeal: false syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/envs/dev/_apps/argocd-tests/app-data.ytt.yaml b/examples/integration-tests/envs/dev/_apps/argocd-tests/app-data.ytt.yaml new file mode 100644 index 00000000..a6b69b0e --- /dev/null +++ b/examples/integration-tests/envs/dev/_apps/argocd-tests/app-data.ytt.yaml @@ -0,0 +1,6 @@ +#@data/values +--- +argocd: + app: + source: + plugin: null diff --git a/examples/integration-tests/envs/dev/env-data.ytt.yaml b/examples/integration-tests/envs/dev/env-data.ytt.yaml index 74807c2d..3234a9da 100644 --- a/examples/integration-tests/envs/dev/env-data.ytt.yaml +++ b/examples/integration-tests/envs/dev/env-data.ytt.yaml @@ -5,6 +5,8 @@ environment: #! applications: # already defined one level above #! - proto: httpbingo # already defined one level above applications: + - proto: ytt-render-test + name: argocd-tests - proto: helm-render-test name: helm-installation - proto: per-chart-override diff --git a/examples/integration-tests/rendered/argocd/mykso-dev/app-argocd-tests.yaml b/examples/integration-tests/rendered/argocd/mykso-dev/app-argocd-tests.yaml new file mode 100644 index 00000000..2d50e053 --- /dev/null +++ b/examples/integration-tests/rendered/argocd/mykso-dev/app-argocd-tests.yaml @@ -0,0 +1,23 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io + name: app-mykso-dev-argocd-tests + namespace: system-argocd +spec: + destination: + name: mykso-dev + namespace: argocd-tests + project: env-mykso-dev + source: + path: examples/integration-tests/rendered/envs/mykso-dev/argocd-tests + repoURL: git@github.com:mykso/myks.git + targetRevision: main + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/rendered/argocd/mykso-dev/app-helm-installation.yaml b/examples/integration-tests/rendered/argocd/mykso-dev/app-helm-installation.yaml index 431ac9f3..4b5eb0f8 100644 --- a/examples/integration-tests/rendered/argocd/mykso-dev/app-helm-installation.yaml +++ b/examples/integration-tests/rendered/argocd/mykso-dev/app-helm-installation.yaml @@ -1,15 +1,15 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: app-mykso-dev-helm-installation namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: env-mykso-dev destination: name: mykso-dev namespace: helm-installation + project: env-mykso-dev source: path: examples/integration-tests/rendered/envs/mykso-dev/helm-installation plugin: @@ -21,5 +21,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-contents-sources.yaml b/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-contents-sources.yaml index f2e7bd92..88ff5e2a 100644 --- a/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-contents-sources.yaml +++ b/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-contents-sources.yaml @@ -1,15 +1,15 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: app-mykso-dev-multiple-contents-sources namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: env-mykso-dev destination: name: mykso-dev namespace: multiple-contents-sources + project: env-mykso-dev source: path: examples/integration-tests/rendered/envs/mykso-dev/multiple-contents-sources plugin: @@ -21,5 +21,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-sources.yaml b/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-sources.yaml index aa502c1e..fc7e6a99 100644 --- a/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-sources.yaml +++ b/examples/integration-tests/rendered/argocd/mykso-dev/app-multiple-sources.yaml @@ -1,15 +1,15 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: app-mykso-dev-multiple-sources namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: env-mykso-dev destination: name: mykso-dev namespace: multiple-sources + project: env-mykso-dev source: path: examples/integration-tests/rendered/envs/mykso-dev/multiple-sources plugin: @@ -21,5 +21,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/rendered/argocd/mykso-dev/app-per-chart-override.yaml b/examples/integration-tests/rendered/argocd/mykso-dev/app-per-chart-override.yaml index 8be1293f..459e717c 100644 --- a/examples/integration-tests/rendered/argocd/mykso-dev/app-per-chart-override.yaml +++ b/examples/integration-tests/rendered/argocd/mykso-dev/app-per-chart-override.yaml @@ -1,15 +1,15 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: app-mykso-dev-per-chart-override namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: env-mykso-dev destination: name: mykso-dev namespace: per-chart-override + project: env-mykso-dev source: path: examples/integration-tests/rendered/envs/mykso-dev/per-chart-override plugin: @@ -21,5 +21,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/rendered/argocd/mykso-dev/app-static-test.yaml b/examples/integration-tests/rendered/argocd/mykso-dev/app-static-test.yaml index e1fe7d14..e3233dee 100644 --- a/examples/integration-tests/rendered/argocd/mykso-dev/app-static-test.yaml +++ b/examples/integration-tests/rendered/argocd/mykso-dev/app-static-test.yaml @@ -1,15 +1,15 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: app-mykso-dev-static-test namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: env-mykso-dev destination: name: mykso-dev namespace: static-test + project: env-mykso-dev source: path: examples/integration-tests/rendered/envs/mykso-dev/static-test plugin: @@ -21,5 +21,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/rendered/argocd/mykso-dev/app-ytt-installation.yaml b/examples/integration-tests/rendered/argocd/mykso-dev/app-ytt-installation.yaml index e963b802..159e2163 100644 --- a/examples/integration-tests/rendered/argocd/mykso-dev/app-ytt-installation.yaml +++ b/examples/integration-tests/rendered/argocd/mykso-dev/app-ytt-installation.yaml @@ -1,15 +1,15 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: app-mykso-dev-ytt-installation namespace: system-argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: env-mykso-dev destination: name: mykso-dev namespace: ytt-installation + project: env-mykso-dev source: path: examples/integration-tests/rendered/envs/mykso-dev/ytt-installation plugin: @@ -21,5 +21,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/integration-tests/rendered/envs/mykso-dev/argocd-tests/rendering-base.yaml b/examples/integration-tests/rendered/envs/mykso-dev/argocd-tests/rendering-base.yaml new file mode 100644 index 00000000..2be09b29 --- /dev/null +++ b/examples/integration-tests/rendered/envs/mykso-dev/argocd-tests/rendering-base.yaml @@ -0,0 +1,6 @@ +kind: rendering +metadata: + name: base +outputYaml: + fromPrototype: true + fromPrototypeAppData: true diff --git a/examples/integration-tests/rendered/envs/mykso-dev/argocd-tests/rendering-proto.yaml b/examples/integration-tests/rendered/envs/mykso-dev/argocd-tests/rendering-proto.yaml new file mode 100644 index 00000000..2fac5357 --- /dev/null +++ b/examples/integration-tests/rendered/envs/mykso-dev/argocd-tests/rendering-proto.yaml @@ -0,0 +1,6 @@ +kind: rendering +metadata: + name: proto +outputYaml: + fromPrototypeOverride: true + fromPrototypeOverrideFromAppData: true diff --git a/examples/simple/rendered/argocd/mykso-dev/app-httpbingo.yaml b/examples/simple/rendered/argocd/mykso-dev/app-httpbingo.yaml index d8de6dd0..9c18f157 100644 --- a/examples/simple/rendered/argocd/mykso-dev/app-httpbingo.yaml +++ b/examples/simple/rendered/argocd/mykso-dev/app-httpbingo.yaml @@ -1,18 +1,17 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: mykso-dev-httpbingo namespace: argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: mykso-dev destination: name: mykso-dev namespace: httpbingo + project: mykso-dev source: path: examples/simple/rendered/envs/mykso-dev/httpbingo - plugin: null repoURL: git@github.com:mykso/myks.git targetRevision: main syncPolicy: @@ -20,5 +19,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/examples/simple/rendered/argocd/mykso-prod/app-httpbingo.yaml b/examples/simple/rendered/argocd/mykso-prod/app-httpbingo.yaml index c479b1d3..b6f7a9ca 100644 --- a/examples/simple/rendered/argocd/mykso-prod/app-httpbingo.yaml +++ b/examples/simple/rendered/argocd/mykso-prod/app-httpbingo.yaml @@ -1,18 +1,17 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: + finalizers: + - resources-finalizer.argocd.argoproj.io name: mykso-prod-httpbingo namespace: argocd - finalizers: - - resources-finalizer.argocd.argoproj.io spec: - project: mykso-prod destination: name: mykso-prod namespace: httpbingo + project: mykso-prod source: path: examples/simple/rendered/envs/mykso-prod/httpbingo - plugin: null repoURL: git@github.com:mykso/myks.git targetRevision: main syncPolicy: @@ -20,5 +19,5 @@ spec: prune: true selfHeal: true syncOptions: - - CreateNamespace=true - - ServerSideApply=true + - CreateNamespace=true + - ServerSideApply=true diff --git a/go.mod b/go.mod index 1b876f61..e2b5af05 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,13 @@ module github.com/mykso/myks -go 1.22.5 +go 1.23.3 + +toolchain go1.23.5 require ( - carvel.dev/vendir v0.42.0 - carvel.dev/ytt v0.50.0 - github.com/alecthomas/chroma/v2 v2.14.0 + carvel.dev/vendir v0.43.0 + carvel.dev/ytt v0.51.1 + github.com/alecthomas/chroma/v2 v2.15.0 github.com/cppforlife/go-cli-ui v0.0.0-20220622150351-995494831c6c github.com/creasty/defaults v1.8.0 github.com/logrusorgru/aurora/v4 v4.0.0 @@ -13,15 +15,15 @@ require ( github.com/rs/zerolog v1.33.0 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 - golang.org/x/sync v0.8.0 - golang.org/x/term v0.25.0 + golang.org/x/sync v0.10.0 + golang.org/x/term v0.28.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - carvel.dev/imgpkg v0.43.1 // indirect + carvel.dev/imgpkg v0.44.0 // indirect cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/Azure/azure-sdk-for-go v55.0.0+incompatible // indirect @@ -56,17 +58,16 @@ require ( github.com/cppforlife/color v1.9.1-0.20200716202919-6706ac40b835 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dimchansky/utfbom v1.1.0 // indirect - github.com/dlclark/regexp2 v1.11.0 // indirect - github.com/docker/cli v25.0.6+incompatible // indirect + github.com/dlclark/regexp2 v1.11.4 // indirect + github.com/docker/cli v27.1.1+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v25.0.6+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/fatih/color v1.15.0 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-containerregistry v0.20.0 // indirect + github.com/google/go-containerregistry v0.20.2 // indirect github.com/google/go-github v17.0.0+incompatible // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect @@ -99,10 +100,10 @@ require ( github.com/vbatts/tar-split v0.11.3 // indirect github.com/vito/go-interact v1.0.1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.28.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.19.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index 253fd2d8..32f8087a 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -carvel.dev/imgpkg v0.43.1 h1:AjvY2Rpz7FIRd1jxOHMyAZwAV6MiqKOLyjT+gzhznbI= -carvel.dev/imgpkg v0.43.1/go.mod h1:mLKnJumG8xtUY4ItDHZCj8XFfCwCdIr26pyxSvP3EPo= -carvel.dev/vendir v0.42.0 h1:5uz9rGq7n1ylwDBBB1tYutfimowGBAYKpHMVyxHGH68= -carvel.dev/vendir v0.42.0/go.mod h1:yE0A4PAEM7YSxV8Q0VIlXHNqISOJ/LnqMluMi7tX1C8= -carvel.dev/ytt v0.50.0 h1:otS2H45ya406sikV17k9FP9Xo0MOVwbHByuA+cPvc4E= -carvel.dev/ytt v0.50.0/go.mod h1:qnB4lXG2eR1F8f9sid21DYzU8hFGFAx/7HO2pvUysHk= +carvel.dev/imgpkg v0.44.0 h1:5f7LZKn8MALx2xldwNXm5TD6vn9NDQuHJs8Nag2Fr0Y= +carvel.dev/imgpkg v0.44.0/go.mod h1:DmoiVp9De4Om38wrc1ooOC12alHytoWd4dWtqYwo4wQ= +carvel.dev/vendir v0.43.0 h1:TEqLRQK4S/4rzyJEKB+ULrkS1BQSGUG5ZucBFCbZFxI= +carvel.dev/vendir v0.43.0/go.mod h1:pK7tOW8jwz2CdwL4VirKwu4G7FoOn5HQ38++T0I0E/I= +carvel.dev/ytt v0.51.1 h1:XWM+9tA+rJnhSel3dJf1jgrCES2wHw68cclkQhZcNRM= +carvel.dev/ytt v0.51.1/go.mod h1:bvN7TWCAHhpPgdulWTQ+gi80aR6TOZ1PJPOEHcKtvQY= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= @@ -40,10 +40,10 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE= -github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E= -github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I= +github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= +github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc= +github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= @@ -109,14 +109,12 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= -github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/docker/cli v25.0.6+incompatible h1:F1mCw1kUGixOkM8WQbcG5kniPvP8XCFxreFxl4b/UnY= -github.com/docker/cli v25.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= +github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= +github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= -github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= @@ -176,8 +174,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.0 h1:wRqHpOeVh3DnenOrPy9xDOLdnLatiGuuNRVelR2gSbg= -github.com/google/go-containerregistry v0.20.0/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= +github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= @@ -334,8 +332,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= @@ -354,8 +353,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +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-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= @@ -381,8 +380,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +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.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= @@ -393,8 +392,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -423,24 +422,20 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.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/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.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-20220411215600-e5f449aeb171/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -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/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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= diff --git a/internal/myks/application.go b/internal/myks/application.go index b69278f6..22bcefbc 100644 --- a/internal/myks/application.go +++ b/internal/myks/application.go @@ -119,13 +119,14 @@ func (a *Application) collectDataFiles() { a.yttDataFiles = append(a.yttDataFiles, environmentDataFiles...) protoDataFile := filepath.Join(a.Prototype, a.e.g.ApplicationDataFileName) - if ok, err := isExist(protoDataFile); ok && err == nil { - a.yttDataFiles = append(a.yttDataFiles, protoDataFile) + if files, err := filepath.Glob(protoDataFile); err == nil { + a.yttDataFiles = append(a.yttDataFiles, files...) } protoOverrideDataFiles := a.e.collectBySubpath(filepath.Join(a.e.g.PrototypeOverrideDir, a.prototypeDirName(), a.e.g.ApplicationDataFileName)) a.yttDataFiles = append(a.yttDataFiles, protoOverrideDataFiles...) - overrideDataFiles := append(protoOverrideDataFiles, a.e.collectBySubpath(filepath.Join(a.e.g.AppsDir, a.Name, a.e.g.ApplicationDataFileName))...) + + overrideDataFiles := a.e.collectBySubpath(filepath.Join(a.e.g.AppsDir, a.Name, a.e.g.ApplicationDataFileName)) a.yttDataFiles = append(a.yttDataFiles, overrideDataFiles...) } diff --git a/internal/myks/assets/data-schema.ytt.yaml b/internal/myks/assets/data-schema.ytt.yaml index 942edcce..e5d673fd 100644 --- a/internal/myks/assets/data-schema.ytt.yaml +++ b/internal/myks/assets/data-schema.ytt.yaml @@ -17,101 +17,107 @@ argocd: namespace: argocd app: #! If not set, the name of the currently rendered application is used. - name: "" + name: '' #! Prefix of the ArgoCD application name. - prefix: "" + prefix: '' #! List of finalizers of the ArgoCD application. #! See https://github.com/argoproj/argo-cd/blob/dc8d7290/docs/user-guide/app_deletion.md #@schema/default ["resources-finalizer.argocd.argoproj.io"] - finalizers: [""] + finalizers: [''] destination: #! spec.destination.name of the ArgoCD application. #! If not set, defaults to the name of the current environment. - name: "" + name: '' #! spec.destination.server of the ArgoCD application. #! If set, used instead of spec.destination.name. - server: "" + server: '' #! spec.destination.namespace of the ArgoCD application. #! If not set, defaults to argocd.app.name. - namespace: "" + namespace: '' source: #! spec.source.path of the ArgoCD application. #! If not set, defaults to the destination path of the currently rendered application. #! With the default myks configuration: `rendered/envs//` - path: "" + path: '' #! spec.source.plugin of the ArgoCD application. #@schema/type any=True plugin: #! spec.source.repoURL of the ArgoCD application. #! If not set, defaults to the current git repository URL. - repoURL: "" + repoURL: '' #! spec.source.targetRevision of the ArgoCD application. #! If not set, defaults to the current git branch. - targetRevision: "" + targetRevision: '' env: #! If not set, the name of the currently rendered environment is used (environment.id). - name: "" + name: '' #! Prefix of a target cluster name. - prefix: "" + prefix: '' #! If set to true, a dummy secret is generated for the target cluster. #! The user has to create an overlay to set correct values for the secret. #! See https://argo-cd.readthedocs.io/en/release-2.8/operator-manual/declarative-setup/#clusters #! TODO: add link to the example overlay. generateSecret: true project: + #! Set to false to disable rendering of the AppProject resource. + #! This can be useful when the AppProject is managed by another tool. + #! In this case, project.name should be set to the name of the existing AppProject. + enabled: true #! If not set, the name of the currently rendered environment is used (environment.id). - name: "" + name: '' #! Prefix of the ArgoCD project name. - prefix: "" + prefix: '' #! spec.destination[0] of the ArgoCD project. #! Add more destinations via overlays, if needed. destination: #! spec.destination.name of the ArgoCD project. #! If not set, defaults to the name of the current environment. - name: "" + name: '' #! spec.destination.server of the ArgoCD project. #! If set, used instead of spec.destination.name. - server: "" + server: '' #! spec.destination.namespace of the ArgoCD project. #! By default, all namespaces are allowed. - namespace: "*" + namespace: '*' environment: #! Unique identifier of the environment, required by myks. #@schema/validation min_len=1 #@schema/nullable - id: "" + id: '' #! List of applications to be deployed in the environment. applications: - #! Prototype of the application. #@schema/validation min_len=1 - proto: "" + proto: '' #! Name of the application. If not defined, the name of the prototype is used. - name: "" + name: '' #! Configuration of the step that renders Helm charts. helm: #! If true, run "helm dependency build" before rendering. This is required for helm charts with dependencies that are pulled from git repositories. buildDependencies: false #! If defined, passed as `--api-version` for `helm-template`. capabilities: - - "" #! e.g. "monitoring.coreos.com/v1" + - '' #! e.g. "monitoring.coreos.com/v1" #! If true, adds `--include-crds` flag to `helm template`. includeCRDs: true #! If defined, passed as a value of `--kube-version` for `helm template`. - kubeVersion: "" + kubeVersion: '' #! If defined, passed as a value of `--namespace` for `helm template`. - namespace: "" + namespace: '' #! Per-chart configuration. Values override the global configuration. #! The `name` field is used to match the chart in the `charts` directory. #! The list is used instead of a map due to a limitation in ytt schema spec. #! See https://github.com/carvel-dev/ytt/issues/656 for more information. #@schema/validation ("chart names must be unique", lambda x: len(set([c["name"] for c in x])) == len(x)) charts: - - buildDependencies: false + - releaseName: '' + #@schema/nullable + buildDependencies: false + #@schema/nullable includeCRDs: false #@schema/validation min_len=1 - name: "" - namespace: "" - releaseName: "" + name: '' + namespace: '' #! Configuration of the step that renders ytt-packages. yttPkg: #! A ytt-package can be rendered as a whole, or can contain multiple sub-packages that should be rendered separately. @@ -119,7 +125,7 @@ yttPkg: #! If empty, the whole package is rendered at once. #! Example: ["sub1", "sub2", "nested/sub3", "nested/sub4"] dirs: - - "" + - '' #! Configuration options for the render step. render: #! If true, the render output file names will include the namespace @@ -128,15 +134,15 @@ render: #! Default values for these options are set by myks. myks: #! Set to the current git branch if available. - gitRepoBranch: "" + gitRepoBranch: '' #! Set to the current git repository URL if available. - gitRepoUrl: "" + gitRepoUrl: '' #! context of the current operation #! EXPERIMENTAL: this configuration section can be changed in the future context: #! application name currently being processed - app: "" + app: '' #! name of prototype including full path (e.g. prototypes/argocd) - prototype: "" + prototype: '' #! rendering step: init, argocd, global_ytt, helm, ytt-pkg, ytt - step: "" + step: '' diff --git a/internal/myks/cache.go b/internal/myks/cache.go index 2ea7c283..064f2eb3 100644 --- a/internal/myks/cache.go +++ b/internal/myks/cache.go @@ -24,7 +24,7 @@ func genCacheName(config map[string]interface{}) (string, error) { } func defaultCacheNamer(config map[string]interface{}) (string, error) { - yaml, err := sortYaml(config) + yaml, err := mapToStableString(config) if err != nil { return "", err } @@ -32,7 +32,7 @@ func defaultCacheNamer(config map[string]interface{}) (string, error) { } func helmCacheNamer(config map[string]interface{}) (string, error) { - yaml, err := sortYaml(config) + yaml, err := mapToStableString(config) if err != nil { return "", err } @@ -48,7 +48,7 @@ func helmCacheNamer(config map[string]interface{}) (string, error) { } func gitCacheNamer(config map[string]interface{}) (string, error) { - yaml, err := sortYaml(config) + yaml, err := mapToStableString(config) if err != nil { return "", err } @@ -68,7 +68,7 @@ func gitCacheNamer(config map[string]interface{}) (string, error) { } func directoryCacheNamer(config map[string]interface{}) (string, error) { - yaml, err := sortYaml(config) + yaml, err := mapToStableString(config) if err != nil { return "", err } diff --git a/internal/myks/environment.go b/internal/myks/environment.go index 3fa61a84..6ab1b6d3 100644 --- a/internal/myks/environment.go +++ b/internal/myks/environment.go @@ -34,9 +34,7 @@ type Environment struct { foundApplications map[string]string } -func NewEnvironment(g *Globe, dir string) (*Environment, error) { - envDataFile := filepath.Join(dir, g.EnvironmentDataFileName) - +func NewEnvironment(g *Globe, dir string, envDataFile string) (*Environment, error) { env := &Environment{ Dir: dir, EnvironmentDataFile: envDataFile, @@ -359,8 +357,8 @@ func (e *Environment) collectBySubpath(subpath string) []string { } currentPath = filepath.Join(currentPath, level) item := filepath.Join(currentPath, subpath) - if ok, err := isExist(item); ok && err == nil { - items = append(items, item) + if files, err := filepath.Glob(item); err == nil { + items = append(items, files...) } } return items diff --git a/internal/myks/globe.go b/internal/myks/globe.go index 27f72407..c6ccf6c5 100644 --- a/internal/myks/globe.go +++ b/internal/myks/globe.go @@ -46,9 +46,9 @@ type Globe struct { // Data values schema file name DataSchemaFileName string `default:"data-schema.ytt.yaml"` // Application data file name - ApplicationDataFileName string `default:"app-data.ytt.yaml"` + ApplicationDataFileName string `default:"app-data*.yaml"` // Environment data file name - EnvironmentDataFileName string `default:"env-data.ytt.yaml"` + EnvironmentDataFileName string `default:"env-data*.yaml"` // Rendered environment data file name RenderedEnvironmentDataFileName string `default:"env-data.yaml"` // Myks runtime data file name @@ -406,20 +406,27 @@ func (g *Globe) collectEnvironmentsInPath(searchPath string) []string { return err } if d != nil && d.IsDir() { - if ok, err := isExist(filepath.Join(path, g.EnvironmentDataFileName)); err != nil { + files, err := filepath.Glob(filepath.Join(path, g.EnvironmentDataFileName)) + if err != nil { return err - } else if ok { - env, err := NewEnvironment(g, path) + } + if len(files) == 0 { + return nil + } + // Try all files in the directory until a valid environment is found + for _, file := range files { + env, err := NewEnvironment(g, path, file) if err == nil { g.environments[path] = env result = append(result, path) - } else { - log.Debug(). - Err(err). - Str("path", path). - Msg("Unable to collect environment, might be base or parent environment. Skipping") + return nil } } + log.Debug(). + Str("path", path). + Strs("files", files). + Msg("Unable to collect environment, might be base or parent environment. Skipping") + } return nil }) diff --git a/internal/myks/plugin_argocd.go b/internal/myks/plugin_argocd.go index 95f9567a..72ccde54 100644 --- a/internal/myks/plugin_argocd.go +++ b/internal/myks/plugin_argocd.go @@ -49,6 +49,10 @@ func (e *Environment) renderArgoCD() (err error) { if err != nil { return err } + if res.Stdout == "" { + log.Info().Msg(e.Msg("ArgoCD environment (AppProject and repository Secret) yaml is empty")) + return nil + } argoDestinationPath := filepath.Join(e.getArgoCDDestinationDir(), getArgoCDEnvFileName(e.ID)) return writeFile(argoDestinationPath, []byte(res.Stdout)) @@ -96,12 +100,18 @@ func (a *Application) renderArgoCD() error { log.Error().Err(err). Str("stdout", res.Stdout). Str("stderr", res.Stderr). - Msg(a.Msg("argocd", "failed to render ArgoCD Application yaml")) + Msg(a.Msg(ArgoCDStepName, "failed to render ArgoCD Application yaml")) + return err + } + + sortedBytes, err := sortYaml([]byte(res.Stdout)) + if err != nil { + log.Error().Err(err).Msg(a.Msg(ArgoCDStepName, "failed to sort ArgoCD Application yaml")) return err } argoDestinationPath := filepath.Join(a.getArgoCDDestinationDir(), getArgoCDAppFileName(a.Name)) - return writeFile(argoDestinationPath, []byte(res.Stdout)) + return writeFile(argoDestinationPath, sortedBytes) } func (a *Application) argoCDPrepareDefaults() (filename string, err error) { diff --git a/internal/myks/render_global_ytt.go b/internal/myks/render_global_ytt.go index e0775622..3fb1c315 100644 --- a/internal/myks/render_global_ytt.go +++ b/internal/myks/render_global_ytt.go @@ -21,15 +21,17 @@ func (g *GlobalYtt) IsAdditive() bool { } func (g *GlobalYtt) Render(previousStepFile string) (string, error) { - var yttFiles []string - - yttFiles = append(yttFiles, g.app.yttDataFiles...) + yttFiles := make([]string, len(g.app.yttDataFiles)) + copy(yttFiles, g.app.yttDataFiles) if previousStepFile != "" { yttFiles = append(yttFiles, previousStepFile) } - yttFiles = append(yttFiles, g.app.e.collectBySubpath(filepath.Join(g.app.e.g.EnvsDir, g.app.e.g.YttStepDirName))...) + // Global or environment-specific ytt files. + // By default, located in `envs//_env/ytt`. + globalYttFiles := g.app.e.collectBySubpath(filepath.Join(g.app.e.g.EnvsDir, g.app.e.g.YttStepDirName)) + yttFiles = append(yttFiles, globalYttFiles...) if len(yttFiles) == 0 { log.Debug().Msg(g.app.Msg(globalYttStepName, "No ytt files found")) diff --git a/internal/myks/smart_mode.go b/internal/myks/smart_mode.go index fde2b65b..288260b6 100644 --- a/internal/myks/smart_mode.go +++ b/internal/myks/smart_mode.go @@ -66,6 +66,13 @@ func (g *Globe) runSmartMode(changedFiles ChangedFiles) EnvAppMap { return regexp.MustCompile("^" + g.GitPathPrefix + sample + "$") } + globToRegexp := func(glob string) string { + r := glob + r = strings.ReplaceAll(r, ".", "\\.") + r = strings.ReplaceAll(r, "*", ".*") + return r + } + // Subdirectories of apps and prototypes are named after plugins plugins := []string{ g.ArgoCDDataDirName, @@ -86,17 +93,17 @@ func (g *Globe) runSmartMode(changedFiles ChangedFiles) EnvAppMap { "env": { e("(" + g.EnvironmentBaseDir + ".*)/" + g.EnvsDir + "/" + g.YttStepDirName + "/.*"), e("(" + g.EnvironmentBaseDir + ".*)/" + g.EnvsDir + "/" + g.ArgoCDDataDirName + "/.*"), - e("(" + g.EnvironmentBaseDir + ".*)/" + g.EnvironmentDataFileName), + e("(" + g.EnvironmentBaseDir + ".*)/" + globToRegexp(g.EnvironmentDataFileName)), }, // Prototype name is the only submatch "prototype": { e(g.PrototypesDir + "/(.+)/" + pluginsPattern + "/.*"), - e(g.PrototypesDir + "/(.+)/" + g.ApplicationDataFileName), + e(g.PrototypesDir + "/(.+)/" + globToRegexp(g.ApplicationDataFileName)), }, // Env path and app name are the submatches "app": { e("(" + g.EnvironmentBaseDir + ".*)/" + g.AppsDir + "/([^/]+)/" + pluginsPattern + "/.*"), - e("(" + g.EnvironmentBaseDir + ".*)/" + g.AppsDir + "/([^/]+)/" + g.ApplicationDataFileName), + e("(" + g.EnvironmentBaseDir + ".*)/" + g.AppsDir + "/([^/]+)/" + globToRegexp(g.ApplicationDataFileName)), }, } diff --git a/internal/myks/smart_mode_test.go b/internal/myks/smart_mode_test.go index 2018a32c..3510ecab 100644 --- a/internal/myks/smart_mode_test.go +++ b/internal/myks/smart_mode_test.go @@ -238,7 +238,7 @@ func TestGlobe_runSmartMode(t *testing.T) { }, { "change to app", - ChangedFiles{"envs/env1/_apps/app1/app-data.ytt.yaml": "M"}, + ChangedFiles{"envs/env1/_apps/app1/app-data.variable.yaml": "M"}, renderedEnvApps, EnvAppMap{ "envs/env1": {"app1"}, diff --git a/internal/myks/templates/argocd/application.ytt.yaml b/internal/myks/templates/argocd/application.ytt.yaml index 940ef473..8ba39e00 100644 --- a/internal/myks/templates/argocd/application.ytt.yaml +++ b/internal/myks/templates/argocd/application.ytt.yaml @@ -5,7 +5,7 @@ #@ app_name = a.app.prefix + (a.env.name or e.id) + "-" + a.app.name #@ env_name = a.env.prefix + (a.env.name or e.id) -#@ project_name = a.project.prefix + (a.env.name or e.id) +#@ project_name = a.project.name or a.project.prefix + (a.env.name or e.id) --- apiVersion: argoproj.io/v1alpha1 @@ -25,6 +25,7 @@ spec: namespace: #@ a.app.destination.namespace or a.app.name source: path: #@ a.app.source.path + #@ if/end a.app.source.plugin: plugin: #@ a.app.source.plugin repoURL: #@ a.app.source.repoURL targetRevision: #@ a.app.source.targetRevision diff --git a/internal/myks/templates/argocd/environment.ytt.yaml b/internal/myks/templates/argocd/environment.ytt.yaml index 8d705a2d..3fcfa3df 100644 --- a/internal/myks/templates/argocd/environment.ytt.yaml +++ b/internal/myks/templates/argocd/environment.ytt.yaml @@ -4,8 +4,9 @@ #@ e = data.values.environment #@ env_name = a.env.prefix + (a.env.name or e.id) -#@ project_name = a.project.prefix + (a.env.name or e.id) +#@ project_name = a.project.name or a.project.prefix + (a.env.name or e.id) +#@ if/end a.project.enabled: --- apiVersion: argoproj.io/v1alpha1 kind: AppProject @@ -18,8 +19,8 @@ metadata: spec: description: #@ 'Project for "{}" environment'.format(env_name) clusterResourceWhitelist: - - group: "*" - kind: "*" + - group: '*' + kind: '*' destinations: - namespace: #@ a.project.destination.namespace #@ if a.project.destination.server: @@ -28,10 +29,10 @@ spec: name: #@ a.project.destination.name or env_name #@ end namespaceResourceWhitelist: - - group: "*" - kind: "*" + - group: '*' + kind: '*' sourceRepos: - - "*" + - '*' #@ if/end a.env.generateSecret: --- diff --git a/internal/myks/util.go b/internal/myks/util.go index cd057c32..67754500 100644 --- a/internal/myks/util.go +++ b/internal/myks/util.go @@ -176,7 +176,7 @@ func unmarshalYamlToMap(filePath string) (map[string]interface{}, error) { return config, nil } -func sortYaml(yaml map[string]interface{}) (string, error) { +func mapToStableString(yaml map[string]interface{}) (string, error) { if yaml == nil { return "", nil } @@ -188,6 +188,22 @@ func sortYaml(yaml map[string]interface{}) (string, error) { return sorted.String(), nil } +func sortYaml(content []byte) ([]byte, error) { + var obj map[string]interface{} + if err := yaml.Unmarshal(content, &obj); err != nil { + return nil, err + } + + var data bytes.Buffer + enc := yaml.NewEncoder(&data) + enc.SetIndent(2) + err := enc.Encode(obj) + if err != nil { + return nil, err + } + return data.Bytes(), nil +} + func hashString(s string) string { h := fnv.New64a() h.Write([]byte(s)) diff --git a/internal/myks/util_test.go b/internal/myks/util_test.go index 083d6718..6953a2b4 100644 --- a/internal/myks/util_test.go +++ b/internal/myks/util_test.go @@ -34,7 +34,7 @@ func Test_hash(t *testing.T) { } } -func Test_sortYaml(t *testing.T) { +func Test_mapToStableString(t *testing.T) { tests := []struct { name string args map[string]interface{} @@ -62,13 +62,13 @@ func Test_sortYaml(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := sortYaml(tt.args) + got, err := mapToStableString(tt.args) if (err != nil) != tt.wantErr { - t.Errorf("sortYaml() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("mapToStableString() error = %v, wantErr %v", err, tt.wantErr) return } if got != tt.want { - t.Errorf("sortYaml() got = %v, wantArgs %v", got, tt.want) + t.Errorf("mapToStableString() got = %v, wantArgs %v", got, tt.want) } }) } diff --git a/renovate.json5 b/renovate.json5 index 1d030fa6..924042fe 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -2,7 +2,8 @@ { $schema: "https://docs.renovatebot.com/renovate-schema.json", extends: [ - "config:base" + "config:base", + "helpers:pinGitHubActionDigests", ], packageRules: [ {