Compare commits

...

61 Commits

Author SHA1 Message Date
Matheus Pimenta 124402b53a
Merge pull request #1472 from dgunzy/bump-ssa-v0.49.0
Bump pkg/ssa to v0.49.0 for CABundle validation fix
2025-06-29 16:56:18 +01:00
Daniel Guns 8e90ab8008
Bump pkg/ssa to v0.49.0 for CABundle validation fix
Includes fix for #800: Remove CABundle from CRDs if cert is invalid

Signed-off-by: Daniel Guns <danbguns@gmail.com>
2025-06-29 12:39:09 -03:00
Matheus Pimenta 8c1d87ba6a
Merge pull request #1470 from cappyzawa/update-kustomize-v5.7.0
Update kustomize to v5.7.0 and add regression test for multiple patch delete
2025-06-29 16:01:53 +01:00
cappyzawa 8479377cd7
Add regression test for multiple patch delete in strategic merge patches
This test ensures that the controller properly handles multiple
$patch: delete directives in strategic merge patches, which was
causing panic errors in kustomize v5.6.0 but is now fixed in v5.7.0.

The test includes two scenarios:
- Multiple delete directives in a single patch (the main fix)
- Multiple delete directives in separate patches (previously a workaround)

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-29 15:38:51 +09:00
cappyzawa ebee7880e7
Update kustomize dependency from v5.6.0 to v5.7.0
The v5.7.0 release fixes panic issues that occur when using multiple
$patch: delete directives in a single strategic merge patch. This was
causing kustomize build to fail with nil pointer dereference errors.

This change updates:
- sigs.k8s.io/kustomize/api from v0.19.0 to v0.20.0
- sigs.k8s.io/kustomize/kyaml from v0.19.0 to v0.20.0
- sigs.k8s.io/yaml from v1.4.0 to v1.5.0 (dependency update)

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-29 15:14:05 +09:00
Stefan Prodan 9f784c5e9f
Merge pull request #1463 from fluxcd/dependabot-up
Update dependabot config
2025-05-28 16:46:19 +03:00
Stefan Prodan 07837f603c
Update dependabot config
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-28 16:35:40 +03:00
Matheus Pimenta ee8981f35d
Merge pull request #1462 from fluxcd/update-labels
Add 1.6.x release label
2025-05-28 14:32:06 +01:00
Matheus Pimenta 40a75725dd
Add 1.6.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-28 14:22:47 +01:00
Matheus Pimenta f1cfd9f0c8
Merge pull request #1461 from fluxcd/release/v1.6.x
Release/v1.6.x
2025-05-28 14:20:21 +01:00
Matheus Pimenta f54038e15d
Merge pull request #1460 from fluxcd/release-v1.6.0
Release v1.6.0
2025-05-28 13:39:03 +01:00
Matheus Pimenta 6efc3ebe0a
Release v1.6.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-28 13:20:38 +01:00
Matheus Pimenta 9eb8ca73ca
Add changelog entry for v1.6.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-28 13:19:53 +01:00
Stefan Prodan 24e54da3cf
Merge pull request #1458 from fluxcd/oci-ga
Update controller to OCIRepository v1 (GA)
2025-05-28 13:53:54 +03:00
Stefan Prodan ff76a91987
Update controller to OCIRepository v1 (GA)
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-28 13:24:44 +03:00
Matheus Pimenta f2db6a2db6
Update dependencies
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-28 10:49:38 +01:00
Stefan Prodan ada569f859
Merge pull request #1448 from fluxcd/dependabot/github_actions/ci-b758b462f2
Bump the ci group across 1 directory with 4 updates
2025-05-27 10:42:17 +03:00
dependabot[bot] 1d32962c17
Bump the ci group across 1 directory with 4 updates
Bumps the ci group with 4 updates in the / directory: [actions/setup-go](https://github.com/actions/setup-go), [docker/build-push-action](https://github.com/docker/build-push-action), [anchore/sbom-action](https://github.com/anchore/sbom-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `actions/setup-go` from 5.4.0 to 5.5.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](0aaccfd150...d35c59abb0)

Updates `docker/build-push-action` from 6.16.0 to 6.17.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](14487ce63c...1dc7386353)

Updates `anchore/sbom-action` from 0.19.0 to 0.20.0
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](9f73021414...e11c554f70)

Updates `github/codeql-action` from 3.28.16 to 3.28.17
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](28deaeda66...60168efe1c)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-version: 6.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-version: 3.28.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-27 07:31:55 +00:00
Stefan Prodan e537b99a17
Merge pull request #1456 from fluxcd/rfc-0010-docs
[RFC-0010] Link workload identity docs to complete guide
2025-05-27 09:01:57 +03:00
Matheus Pimenta 8303b0854d
[RFC-0010] Link workload identity docs to complete guide
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-26 23:46:29 +01:00
Stefan Prodan 55be958932
Merge pull request #1444 from fluxcd/gc-wait-for-termination
Implement `WaitForTermination` deletion policy
2025-05-23 12:29:21 +02:00
Matheus Pimenta c25690c4c1
Merge pull request #1449 from fluxcd/rfc-0010-feature-gate
[RFC-0010] Introduce feature gate
2025-05-23 07:59:07 +01:00
Matheus Pimenta 0d6ab9f762
[RFC-0010] Introduce feature gate
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-19 14:18:35 +01:00
Stefan Prodan 413118e9a7
Document The `WaitForTermination` policy
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-13 16:31:33 +03:00
Stefan Prodan 98adddbf2e
Implement waiting for termination at finalization
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-13 13:36:54 +03:00
Stefan Prodan 92070be338
Update `fluxcd/pkg/ssa` to v0.47.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-13 12:52:40 +03:00
Stefan Prodan c54d9f6bec
Add `WaitForTermination` option to DeletionPolicy
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-13 12:51:57 +03:00
Matheus Pimenta d775ed3a19
Merge pull request #1426 from fluxcd/rfc-0010
[RFC-0010] Introduce object-level workload identity for KMS decryption
2025-05-07 17:58:58 +01:00
Matheus Pimenta ac963f92f4
[RFC-0010] Introduce KMS provider decryption with service account
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-07 17:43:35 +01:00
Matheus Pimenta d157045895
Merge pull request #1436 from fluxcd/fix-1428
Fix performance regression due to using client without cache
2025-04-29 14:00:56 +01:00
Matheus Pimenta 361a28eed9
Fix performance regression due to using client without cache
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-04-29 13:48:31 +01:00
Stefan Prodan 690c8c8a74
Merge pull request #1433 from fluxcd/dependabot/github_actions/ci-4c7c75f92f
Bump the ci group across 1 directory with 14 updates
2025-04-28 14:56:55 +03:00
dependabot[bot] 88ccb5a3d5
Bump the ci group across 1 directory with 14 updates
Bumps the ci group with 14 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [korthout/backport-action](https://github.com/korthout/backport-action) | `3.1.0` | `3.2.0` |
| [actions/setup-go](https://github.com/actions/setup-go) | `5.3.0` | `5.4.0` |
| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3.4.0` | `3.6.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.9.0` | `3.10.0` |
| [actions/cache](https://github.com/actions/cache) | `4.2.0` | `4.2.3` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.13.0` | `6.16.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.3.0` | `3.4.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.6.1` | `5.7.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.8.0` | `3.8.2` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.18.0` | `0.19.0` |
| [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) | `6.2.1` | `6.3.0` |
| [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) | `2.0.0` | `2.1.0` |
| [fossa-contrib/fossa-action](https://github.com/fossa-contrib/fossa-action) | `3.0.0` | `3.0.1` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.9` | `3.28.16` |



Updates `korthout/backport-action` from 3.1.0 to 3.2.0
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](be567af183...436145e922)

Updates `actions/setup-go` from 5.3.0 to 5.4.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](f111f3307d...0aaccfd150)

Updates `docker/setup-qemu-action` from 3.4.0 to 3.6.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](4574d27a47...29109295f8)

Updates `docker/setup-buildx-action` from 3.9.0 to 3.10.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](f7ce87c1d6...b5ca514318)

Updates `actions/cache` from 4.2.0 to 4.2.3
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](1bd1e32a3b...5a3ec84eff)

Updates `docker/build-push-action` from 6.13.0 to 6.16.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](ca877d9245...14487ce63c)

Updates `docker/login-action` from 3.3.0 to 3.4.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](9780b0c442...74a5d14239)

Updates `docker/metadata-action` from 5.6.1 to 5.7.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](369eb591f4...902fa8ec7d)

Updates `sigstore/cosign-installer` from 3.8.0 to 3.8.2
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](c56c2d3e59...3454372f43)

Updates `anchore/sbom-action` from 0.18.0 to 0.19.0
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](f325610c9f...9f73021414)

Updates `goreleaser/goreleaser-action` from 6.2.1 to 6.3.0
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](90a3faa9d0...9c156ee8a1)

Updates `slsa-framework/slsa-github-generator` from 2.0.0 to 2.1.0
- [Release notes](https://github.com/slsa-framework/slsa-github-generator/releases)
- [Changelog](https://github.com/slsa-framework/slsa-github-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/slsa-framework/slsa-github-generator/compare/v2.0.0...v2.1.0)

Updates `fossa-contrib/fossa-action` from 3.0.0 to 3.0.1
- [Release notes](https://github.com/fossa-contrib/fossa-action/releases)
- [Changelog](https://github.com/fossa-contrib/fossa-action/blob/master/CHANGELOG.md)
- [Commits](cdc5065bcd...3d2ef181b1)

Updates `github/codeql-action` from 3.28.9 to 3.28.16
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](9e8d0789d4...28deaeda66)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: actions/setup-go
  dependency-version: 5.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-qemu-action
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-buildx-action
  dependency-version: 3.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: actions/cache
  dependency-version: 4.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-version: 6.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/login-action
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/metadata-action
  dependency-version: 5.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-version: 0.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: slsa-framework/slsa-github-generator
  dependency-version: 2.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: fossa-contrib/fossa-action
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-version: 3.28.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 11:35:19 +00:00
Stefan Prodan 8079722607
Merge pull request #1435 from fluxcd/ks-1.33
Update to Kubernetes 1.33.0 and Go 1.24.0
2025-04-28 14:32:58 +03:00
Stefan Prodan 3ac784dbc8
Update to Kubernetes 1.33.0 and Go 1.24.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-28 14:12:22 +03:00
Stefan Prodan a5e315e923
Merge pull request #1429 from fluxcd/controller-runtime-v0.20.4
Update controller-runtime to v0.20.4
2025-04-24 12:29:28 +03:00
Stefan Prodan 59bbc527b6
Update controller-runtime to v0.20.4
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-23 09:59:46 +03:00
Stefan Prodan e2794590cd
Merge pull request #1427 from florensie/patch-1
docs: Update link to envsubst lib
2025-04-23 09:53:03 +03:00
Florens Pauwels a8edbb96d1
Update link to envsubst lib
Signed-off-by: Florens Pauwels <github@florens.be>
2025-04-18 12:57:38 +02:00
Stefan Prodan 60afb73327
Merge pull request #1396 from norman-zon/suspension-event-log
Skip emitting events for suspended Kustomizations
2025-04-15 10:26:35 +03:00
Norman Stetter 2d89eb6010
feat: prevent no-op reconciles
There are edge cases where a reonciliation can be triggered on a
suspended Kustomization, mainly through changes in a source.
In these cases a "no-op" reconciliation occurs, which can be confusing
for the user. This returns early if the Kustomization ist suspended.

Signed-off-by: Norman Stetter <85173861+norman-zon@users.noreply.github.com>
2025-04-15 08:47:28 +02:00
Stefan Prodan 35fd6c158b
Merge pull request #1413 from zevisert/docs/add-mention-CEL-macros
docs: mention CEL macros when discussing health check expressions
2025-04-10 10:32:42 +03:00
Matheus Pimenta 2437aaf32e
Merge pull request #1414 from fluxcd/dependabot/go_modules/go-deps-2507ff55c6
Bump github.com/getsops/sops/v3 from 3.10.0 to 3.10.1 in the go-deps group
2025-04-01 09:20:51 +01:00
dependabot[bot] b715ca0e60
Bump github.com/getsops/sops/v3 in the go-deps group
Bumps the go-deps group with 1 update: [github.com/getsops/sops/v3](https://github.com/getsops/sops).


Updates `github.com/getsops/sops/v3` from 3.10.0 to 3.10.1
- [Release notes](https://github.com/getsops/sops/releases)
- [Changelog](https://github.com/getsops/sops/blob/main/CHANGELOG.md)
- [Commits](https://github.com/getsops/sops/compare/v3.10.0...v3.10.1)

---
updated-dependencies:
- dependency-name: github.com/getsops/sops/v3
  dependency-version: 3.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 02:49:32 +00:00
Zev Isert 6c7da05677
docs: mention CEL macros when discussing health check expressions
Signed-off-by: Zev Isert <dev@zevisert.ca>
2025-03-31 16:58:00 -07:00
Matheus Pimenta 12628b8187
Merge pull request #1410 from fluxcd/dependabot/go_modules/go-deps-0ef529e661
Bump the go-deps group across 1 directory with 3 updates
2025-03-31 05:29:54 +01:00
Matheus Pimenta cb67f6f015
Fix decryption test due to SOPS breaking change
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-03-31 05:16:08 +01:00
dependabot[bot] 6b139adfaa
Bump the go-deps group across 1 directory with 3 updates
Bumps the go-deps group with 2 updates in the / directory: [github.com/getsops/sops/v3](https://github.com/getsops/sops) and [github.com/onsi/gomega](https://github.com/onsi/gomega).


Updates `github.com/getsops/sops/v3` from 3.9.4 to 3.10.0
- [Release notes](https://github.com/getsops/sops/releases)
- [Changelog](https://github.com/getsops/sops/blob/main/CHANGELOG.md)
- [Commits](https://github.com/getsops/sops/compare/v3.9.4...v3.10.0)

Updates `github.com/onsi/gomega` from 1.36.2 to 1.36.3
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.36.2...v1.36.3)

Updates `golang.org/x/net` from 0.35.0 to 0.38.0
- [Commits](https://github.com/golang/net/compare/v0.35.0...v0.38.0)

---
updated-dependencies:
- dependency-name: github.com/getsops/sops/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 02:39:46 +00:00
Matheus Pimenta 860d5f8339
Merge pull request #1401 from fluxcd/upgrade-deps
Update `fluxcd/pkg/runtime` to v0.58.0
2025-03-27 11:53:57 +00:00
Matheus Pimenta 42b9036bf3
Update `fluxcd/pkg/runtime` to v0.58.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-03-27 11:35:53 +00:00
Matheus Pimenta dc0e5853c0
Merge pull request #1381 from fluxcd/pick-changelog-v1.5.1
Add changelog entry for v1.5.1
2025-02-25 15:20:46 +00:00
Matheus Pimenta 6c001f2862
Add changelog entry for v1.5.1
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
(cherry picked from commit c6cdd95e84)
2025-02-25 14:45:45 +00:00
Stefan Prodan c353f1e532
Merge pull request #1377 from fluxcd/lazy-restmapper
Use the dynamic RESTMapper from controller-runtime v0.19
2025-02-25 15:50:09 +02:00
Stefan Prodan 4ad6f256f6
Update `fluxcd/pkg/runtime` to v0.54.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-02-25 14:31:49 +02:00
Stefan Prodan 12b3acbaaa
Add test for RESTMapper with CRD/CR
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-02-25 13:34:57 +02:00
Stefan Prodan 8b6f4bc6e9
Use lazy restmapper vendored from controller-runtime v0.19
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-02-25 09:30:03 +02:00
Matheus Pimenta 0837a4217a
Merge pull request #1372 from fluxcd/redact-values
Fix secret value showing up in logs
2025-02-24 16:32:42 +00:00
Matheus Pimenta a7e4927fed
Fix secret value showing up in logs
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-24 15:22:35 +00:00
Matheus Pimenta 444b8d265e
Merge pull request #1367 from fluxcd/update-labels
Add 1.5.x release label
2025-02-18 18:30:00 +00:00
Matheus Pimenta adfde39e9a
Add 1.5.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-18 18:13:38 +00:00
Matheus Pimenta 66e0c439c0
Merge pull request #1366 from fluxcd/release/v1.5.x
Release/v1.5.x
2025-02-18 18:11:26 +00:00
47 changed files with 4422 additions and 1087 deletions

View File

@ -5,7 +5,7 @@ updates:
directory: "/"
labels: ["dependencies"]
schedule:
interval: "daily"
interval: "monthly"
groups:
go-deps:
patterns:
@ -31,4 +31,4 @@ updates:
patterns:
- "*"
schedule:
interval: "daily"
interval: "monthly"

6
.github/labels.yaml vendored
View File

@ -32,3 +32,9 @@
- name: backport:release/v1.4.x
description: To be backported to release/v1.4.x
color: '#ffd700'
- name: backport:release/v1.5.x
description: To be backported to release/v1.5.x
color: '#ffd700'
- name: backport:release/v1.6.x
description: To be backported to release/v1.6.x
color: '#ffd700'

View File

@ -20,7 +20,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs
uses: korthout/backport-action@be567af183754f6a5d831ae90f648954763f17f5 # v3.1.0
uses: korthout/backport-action@436145e922f9561fc5ea157ff406f21af2d6b363 # v3.2.0
# xref: https://github.com/korthout/backport-action#inputs
with:
# Use token to allow workflows to be triggered for the created PR

View File

@ -14,9 +14,9 @@ jobs:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.23.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod

View File

@ -17,12 +17,12 @@ jobs:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup QEMU
uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # v3.4.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Cache Docker layers
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: cache
with:
path: /tmp/.buildx-cache
@ -30,9 +30,9 @@ jobs:
restore-keys: |
${{ runner.os }}-buildx-ghcache-
- name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.23.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod

View File

@ -17,14 +17,14 @@ jobs:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup QEMU
uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # v3.4.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
with:
buildkitd-flags: "--debug"
- name: Build multi-arch container image
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
push: false
builder: ${{ steps.buildx.outputs.name }}

View File

@ -42,24 +42,24 @@ jobs:
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
- name: Setup QEMU
uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # v3.4.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Login to GitHub Container Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: fluxcdbot
password: ${{ secrets.GHCR_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: fluxcdbot
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
- name: Generate images meta
id: meta
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: |
fluxcd/${{ env.CONTROLLER }}
@ -68,7 +68,7 @@ jobs:
type=raw,value=${{ steps.prep.outputs.VERSION }}
- name: Publish images
id: build-push
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
sbom: true
provenance: true
@ -79,7 +79,7 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
- uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
- name: Sign images
env:
COSIGN_EXPERIMENTAL: 1
@ -92,11 +92,11 @@ jobs:
mkdir -p config/release
kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml
kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml
- uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
- uses: anchore/sbom-action/download-syft@e11c554f704a0b820cbf8c51673f6945e0731532 # v0.20.0
- name: Create release and SBOM
id: run-goreleaser
if: startsWith(github.ref, 'refs/tags/v')
uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6.2.1
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
with:
version: latest
args: release --clean --skip=validate
@ -123,7 +123,7 @@ jobs:
id-token: write # for creating OIDC tokens for signing.
contents: write # for uploading attestations to GitHub releases.
if: startsWith(github.ref, 'refs/tags/v')
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with:
provenance-name: "provenance.intoto.jsonl"
base64-subjects: "${{ needs.release.outputs.hashes }}"
@ -136,7 +136,7 @@ jobs:
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations.
if: startsWith(github.ref, 'refs/tags/v')
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: ${{ needs.release.outputs.image_url }}
digest: ${{ needs.release.outputs.image_digest }}
@ -151,7 +151,7 @@ jobs:
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations.
if: startsWith(github.ref, 'refs/tags/v')
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: ghcr.io/${{ needs.release.outputs.image_url }}
digest: ${{ needs.release.outputs.image_digest }}

View File

@ -20,7 +20,7 @@ jobs:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run FOSSA scan and upload build data
uses: fossa-contrib/fossa-action@cdc5065bcdee31a32e47d4585df72d66e8e941c2 # v3.0.0
uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1
with:
# FOSSA Push-Only API Token
fossa-api-key: 5ee8bf422db1471e0bcf2bcb289185de
@ -33,20 +33,20 @@ jobs:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.23.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod
- name: Initialize CodeQL
uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: go
# xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# xref: https://codeql.github.com/codeql-query-help/go/
queries: security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18

View File

@ -2,6 +2,71 @@
All notable changes to this project are documented in this file.
## 1.6.0
**Release date:** 2025-05-28
This minor release comes with various bug fixes and improvements.
Kustomization API now supports object-level workload identity by setting
`.spec.decryption.serviceAccountName` to the name of a service account
in the same namespace that has been configured with appropriate cloud
permissions. For this feature to work, the controller feature gate
`ObjectLevelWorkloadIdentity` must be enabled. See a complete guide
[here](https://fluxcd.io/flux/integrations/).
Kustomization API now supports the value `WaitForTermination` for the
`.spec.deletionPolicy` field. This instructs the controller to wait for the
deletion of all resources managed by the Kustomization before allowing the
Kustomization itself to be deleted. See docs
[here](https://fluxcd.io/flux/components/kustomize/kustomizations/#deletion-policy).
In addition, the Kubernetes dependencies have been updated to v1.33 and
various other controller dependencies have been updated to their latest version.
The controller is now built with Go 1.24.
Fixes:
- Fix performance regression due to using client without cache
[#1436](https://github.com/fluxcd/kustomize-controller/pull/1436)
- Fix secret value showing up in logs
[#1372](https://github.com/fluxcd/kustomize-controller/pull/1372)
Improvements:
- [RFC-0010] Introduce KMS provider decryption with service account
[#1426](https://github.com/fluxcd/kustomize-controller/pull/1426)
[#1449](https://github.com/fluxcd/kustomize-controller/pull/1449)
[#1456](https://github.com/fluxcd/kustomize-controller/pull/1456)
- Add `WaitForTermination` option to DeletionPolicy
[#1444](https://github.com/fluxcd/kustomize-controller/pull/1444)
- Skip emitting events for suspended Kustomizations
[#1396](https://github.com/fluxcd/kustomize-controller/pull/1396)
- Various dependency updates
[#1458](https://github.com/fluxcd/kustomize-controller/pull/1458)
[#1448](https://github.com/fluxcd/kustomize-controller/pull/1448)
[#1433](https://github.com/fluxcd/kustomize-controller/pull/1433)
[#1435](https://github.com/fluxcd/kustomize-controller/pull/1435)
[#1429](https://github.com/fluxcd/kustomize-controller/pull/1429)
[#1414](https://github.com/fluxcd/kustomize-controller/pull/1414)
[#1410](https://github.com/fluxcd/kustomize-controller/pull/1410)
[#1401](https://github.com/fluxcd/kustomize-controller/pull/1401)
## 1.5.1
**Release date:** 2025-02-25
This patch release fixes a bug introduced in v1.5.0
that was causing spurious logging for deprecated API versions
and sometimes failures on health checks.
In addition, all error logs resulting from SOPS decryption
failures have been sanitised.
Fixes:
- Fix secret value showing up in logs
[#1372](https://github.com/fluxcd/kustomize-controller/pull/1372)
- Use lazy restmapper vendored from controller-runtime v0.19
[#1377](https://github.com/fluxcd/kustomize-controller/pull/1377)
## 1.5.0
**Release date:** 2025-02-18

View File

@ -16,7 +16,7 @@ There are a number of dependencies required to be able to run the controller and
## How to run the test suite
Prerequisites:
* Go >= 1.23
* Go >= 1.24
You can run the test suite by simply doing

View File

@ -1,4 +1,4 @@
ARG GO_VERSION=1.23
ARG GO_VERSION=1.24
ARG XX_VERSION=1.6.1
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx

View File

@ -135,8 +135,8 @@ api-docs: gen-crd-api-reference-docs
# Run go mod tidy
tidy:
cd api; rm -f go.sum; go mod tidy -compat=1.23
rm -f go.sum; go mod tidy -compat=1.23
cd api; rm -f go.sum; go mod tidy -compat=1.24
rm -f go.sum; go mod tidy -compat=1.24
# Run go fmt against code
fmt:

View File

@ -41,7 +41,7 @@ the controller performs actions to reconcile the cluster current state with the
* [Get started with Flux](https://fluxcd.io/flux/get-started/)
* [Setup Notifications](https://fluxcd.io/flux/guides/notifications/)
* [Manage Kubernetes secrets with Flux and Mozilla SOPS](https://fluxcd.io/flux/guides/mozilla-sops/)
* [Manage Kubernetes secrets with Flux and SOPS](https://fluxcd.io/flux/guides/mozilla-sops/)
* [How to build, publish and consume OCI Artifacts with Flux](https://fluxcd.io/flux/cheatsheets/oci-artifacts/)
* [Flux and Kustomize FAQ](https://fluxcd.io/flux/faq/#kustomize-questions)

View File

@ -1,35 +1,36 @@
module github.com/fluxcd/kustomize-controller/api
go 1.23.0
go 1.24.0
require (
github.com/fluxcd/pkg/apis/kustomize v1.9.0
github.com/fluxcd/pkg/apis/meta v1.10.0
k8s.io/apiextensions-apiserver v0.32.1
k8s.io/apimachinery v0.32.1
sigs.k8s.io/controller-runtime v0.20.1
github.com/fluxcd/pkg/apis/kustomize v1.10.0
github.com/fluxcd/pkg/apis/meta v1.12.0
k8s.io/apiextensions-apiserver v0.33.0
k8s.io/apimachinery v0.33.0
sigs.k8s.io/controller-runtime v0.21.0
)
// Fix CVE-2022-28948
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
require (
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/tools v0.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -1,14 +1,13 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fluxcd/pkg/apis/kustomize v1.9.0 h1:SJpT1CK58AnTvCpDKeGfMNA0Xud/4VReZNvPe8XkTxo=
github.com/fluxcd/pkg/apis/kustomize v1.9.0/go.mod h1:AZl2GU03oPVue6SUivdiIYd/3mvF94j7t1G2JO26d4s=
github.com/fluxcd/pkg/apis/meta v1.10.0 h1:rqbAuyl5ug7A5jjRf/rNwBXmNl6tJ9wG2iIsriwnQUk=
github.com/fluxcd/pkg/apis/meta v1.10.0/go.mod h1:n7NstXHDaleAUMajcXTVkhz0MYkvEXy1C/eLI/t1xoI=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/fluxcd/pkg/apis/kustomize v1.10.0 h1:47EeSzkQvlQZdH92vHMe2lK2iR8aOSEJq95avw5idts=
github.com/fluxcd/pkg/apis/kustomize v1.10.0/go.mod h1:UsqMV4sqNa1Yg0pmTsdkHRJr7bafBOENIJoAN+3ezaQ=
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg=
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
@ -16,11 +15,9 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
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-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
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/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@ -36,23 +33,22 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
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/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
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/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
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/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -66,26 +62,26 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
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=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
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/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
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=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -97,21 +93,24 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs=
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc=
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5ZtjZnHaE=
sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -34,9 +34,10 @@ const (
IfNotPresentValue = "IfNotPresent"
IgnoreValue = "Ignore"
DeletionPolicyMirrorPrune = "MirrorPrune"
DeletionPolicyDelete = "Delete"
DeletionPolicyOrphan = "Orphan"
DeletionPolicyMirrorPrune = "MirrorPrune"
DeletionPolicyDelete = "Delete"
DeletionPolicyWaitForTermination = "WaitForTermination"
DeletionPolicyOrphan = "Orphan"
)
// KustomizationSpec defines the configuration to calculate the desired state
@ -101,9 +102,9 @@ type KustomizationSpec struct {
// DeletionPolicy can be used to control garbage collection when this
// Kustomization is deleted. Valid values are ('MirrorPrune', 'Delete',
// 'Orphan'). 'MirrorPrune' mirrors the Prune field (orphan if false,
// delete if true). Defaults to 'MirrorPrune'.
// +kubebuilder:validation:Enum=MirrorPrune;Delete;Orphan
// 'WaitForTermination', 'Orphan'). 'MirrorPrune' mirrors the Prune field
// (orphan if false, delete if true). Defaults to 'MirrorPrune'.
// +kubebuilder:validation:Enum=MirrorPrune;Delete;WaitForTermination;Orphan
// +optional
DeletionPolicy string `json:"deletionPolicy,omitempty"`
@ -205,7 +206,18 @@ type Decryption struct {
// +required
Provider string `json:"provider"`
// ServiceAccountName is the name of the service account used to
// authenticate with KMS services from cloud providers. If a
// static credential for a given cloud provider is defined
// inside the Secret referenced by SecretRef, that static
// credential takes priority.
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// The secret name containing the private OpenPGP keys used for decryption.
// A static credential for a cloud provider defined inside the Secret
// takes priority to secret-less authentication with the ServiceAccountName
// field.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
}

View File

@ -86,8 +86,11 @@ spec:
- sops
type: string
secretRef:
description: The secret name containing the private OpenPGP keys
used for decryption.
description: |-
The secret name containing the private OpenPGP keys used for decryption.
A static credential for a cloud provider defined inside the Secret
takes priority to secret-less authentication with the ServiceAccountName
field.
properties:
name:
description: Name of the referent.
@ -95,6 +98,14 @@ spec:
required:
- name
type: object
serviceAccountName:
description: |-
ServiceAccountName is the name of the service account used to
authenticate with KMS services from cloud providers. If a
static credential for a given cloud provider is defined
inside the Secret referenced by SecretRef, that static
credential takes priority.
type: string
required:
- provider
type: object
@ -102,11 +113,12 @@ spec:
description: |-
DeletionPolicy can be used to control garbage collection when this
Kustomization is deleted. Valid values are ('MirrorPrune', 'Delete',
'Orphan'). 'MirrorPrune' mirrors the Prune field (orphan if false,
delete if true). Defaults to 'MirrorPrune'.
'WaitForTermination', 'Orphan'). 'MirrorPrune' mirrors the Prune field
(orphan if false, delete if true). Defaults to 'MirrorPrune'.
enum:
- MirrorPrune
- Delete
- WaitForTermination
- Orphan
type: string
dependsOn:

View File

@ -2,8 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kustomize-system
resources:
- https://github.com/fluxcd/source-controller/releases/download/v1.5.0/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v1.5.0/source-controller.deployment.yaml
- https://github.com/fluxcd/source-controller/releases/download/v1.6.0/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v1.6.0/source-controller.deployment.yaml
- ../crd
- ../rbac
- ../manager

View File

@ -5,4 +5,4 @@ resources:
images:
- name: fluxcd/kustomize-controller
newName: fluxcd/kustomize-controller
newTag: v1.5.0
newTag: v1.6.0

View File

@ -21,6 +21,12 @@ rules:
verbs:
- create
- patch
- apiGroups:
- ""
resources:
- serviceaccounts/token
verbs:
- create
- apiGroups:
- kustomize.toolkit.fluxcd.io
resources:

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: oci

View File

@ -217,8 +217,8 @@ string
<em>(Optional)</em>
<p>DeletionPolicy can be used to control garbage collection when this
Kustomization is deleted. Valid values are (&lsquo;MirrorPrune&rsquo;, &lsquo;Delete&rsquo;,
&lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field (orphan if false,
delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
&lsquo;WaitForTermination&rsquo;, &lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field
(orphan if false, delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
</td>
</tr>
<tr>
@ -574,6 +574,22 @@ string
</tr>
<tr>
<td>
<code>serviceAccountName</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ServiceAccountName is the name of the service account used to
authenticate with KMS services from cloud providers. If a
static credential for a given cloud provider is defined
inside the Secret referenced by SecretRef, that static
credential takes priority.</p>
</td>
</tr>
<tr>
<td>
<code>secretRef</code><br>
<em>
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
@ -583,7 +599,10 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</td>
<td>
<em>(Optional)</em>
<p>The secret name containing the private OpenPGP keys used for decryption.</p>
<p>The secret name containing the private OpenPGP keys used for decryption.
A static credential for a cloud provider defined inside the Secret
takes priority to secret-less authentication with the ServiceAccountName
field.</p>
</td>
</tr>
</tbody>
@ -756,8 +775,8 @@ string
<em>(Optional)</em>
<p>DeletionPolicy can be used to control garbage collection when this
Kustomization is deleted. Valid values are (&lsquo;MirrorPrune&rsquo;, &lsquo;Delete&rsquo;,
&lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field (orphan if false,
delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
&lsquo;WaitForTermination&rsquo;, &lsquo;Orphan&rsquo;). &lsquo;MirrorPrune&rsquo; mirrors the Prune field
(orphan if false, delete if true). Defaults to &lsquo;MirrorPrune&rsquo;.</p>
</td>
</tr>
<tr>

View File

@ -115,7 +115,7 @@ Artifact containing the YAML manifests. It has two required fields:
- `kind`: The Kind of the referred Source object. Supported Source types:
+ [GitRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/gitrepositories.md)
+ [OCIRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1beta2/ocirepositories.md)
+ [OCIRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/ocirepositories.md)
+ [Bucket](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/buckets.md)
- `name`: The Name of the referred Source object.
@ -181,8 +181,16 @@ Valid values:
`true` and orphaned if `false`.
- `Delete` - Ensure the managed resources are deleted before the Kustomization
is deleted.
- `WaitForTermination` - Ensure the managed resources are deleted and wait for
termination before the Kustomization is deleted.
- `Orphan` - Leave the managed resources when the Kustomization is deleted.
The `WaitForTermination` deletion policy blocks and waits for the managed
resources to be removed from etcd by the Kubernetes garbage collector.
The wait time is determined by the `.spec.timeout` field. If a timeout occurs,
the controller will stop waiting for the deletion of the resources,
log an error and will allow the Kustomization to be deleted.
For special cases when the managed resources are removed by other means (e.g.
the deletion of the namespace specified with
[`.spec.targetNamespace`](#target-namespace)), you can set the deletion policy
@ -394,7 +402,10 @@ for the resource to be ready until the timeout is reached. To avoid this,
make sure your CEL expressions are correct. The
[CEL Playground](https://playcel.undistro.io/) is a useful resource for
this task. The input passed to each expression is the custom resource
object itself.
object itself. You can check for field existence with the
[`has(...)` CEL macro](https://github.com/google/cel-spec/blob/master/doc/langdef.md#macros),
just be aware that `has(status)` errors if `status` does not (yet) exist
on the top level of the resource you are using.
It's worth checking if [the library](/flux/cheatsheets/cel-healthchecks/)
has expressions for the custom resources you are using.
@ -639,7 +650,7 @@ absence as if the object had been present but empty, defining no
variables.
This offers basic templating for your manifests including support
for [bash string replacement functions](https://github.com/drone/envsubst) e.g.:
for [bash string replacement functions](https://github.com/fluxcd/pkg/blob/main/envsubst/README.md) e.g.:
- `${var:=default}`
- `${var:position}`
@ -820,33 +831,47 @@ For more information, see [remote clusters/Cluster-API](#remote-clusterscluster-
### Decryption
`.spec.decryption` is an optional field to specify the configuration to decrypt
Secrets, ConfigMaps and patches that are a part of the Kustomization.
Storing Secrets in Git repositories in plain text or base64 is unsafe,
regardless of the visibility or access restrictions of the repository.
Since Secrets are either plain text or `base64` encoded, it's unsafe to store
them in plain text in a public or private Git repository. In order to store
them safely, you can use [Mozilla SOPS](https://github.com/mozilla/sops) and
encrypt your Kubernetes Secret data with [age](https://age-encryption.org/v1/)
and/or [OpenPGP](https://www.openpgp.org) keys, or with provider implementations
like Azure Key Vault, GCP KMS or Hashicorp Vault.
In order to store Secrets safely in Git repositorioes you can use an
encryption provider and the optional field `.spec.decryption` to
configure decryption for Secrets that are a part of the Kustomization.
Also, you may want to encrypt some parts of resources as well. In order to do that,
you may encrypt patches as well.
The only supported encryption provider is [SOPS](https://getsops.io/).
With SOPS you can encrypt your secrets with [age](https://github.com/FiloSottile/age)
or [OpenPGP](https://www.openpgp.org) keys, or with keys from Key Management Services
(KMS), like AWS KMS, Azure Key Vault, GCP KMS or Hashicorp Vault.
**Note:** You must leave `metadata`, `kind` or `apiVersion` in plain text.
An easy way to do this is to limit encrypted keys by appending `--encrypted-regex '^(data|stringData)$'`
to your `sops --encrypt` command.
An easy way to do this is limiting the encrypted keys with the flag
`--encrypted-regex '^(data|stringData)$'` in your `sops encrypt` command.
It has two fields:
The `.spec.decryption` field has the following subfields:
- `.provider`: The secrets decryption provider to be used. This field is required and
the only supported value is `sops`.
- `.secretRef.name`: The name of the secret that contains the keys to be used for
decryption. This field can be omitted when using the
[global decryption](#controller-global-decryption) option.
- `.secretRef.name`: The name of the secret that contains the keys or cloud provider
static credentials for KMS services to be used for decryption.
- `.serviceAccountName`: The name of the service account used for
secret-less authentication with KMS services from cloud providers.
For a complete guide on how to set up authentication for KMS services from
cloud providers, see the integration [docs](/flux/integrations/).
If a static credential for a given cloud provider is defined inside the secret
referenced by `.secretRef`, that static credential takes priority over secret-less
authentication for that provider. If no static credentials are defined for a given
cloud provider inside the secret, secret-less authentication is attempted for that
provider.
If `.serviceAccountName` is specified for secret-less authentication,
it takes priority over [controller global decryption](#controller-global-decryption)
for all cloud providers.
Example:
```yaml
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
@ -860,13 +885,11 @@ spec:
name: repository-with-secrets
decryption:
provider: sops
serviceAccountName: sops-identity
secretRef:
name: sops-keys
name: sops-keys-and-credentials
```
**Note:** For information on Secrets decryption at a controller level, please
refer to [controller global decryption](#controller-global-decryption).
The Secret's `.data` section is expected to contain entries with decryption
keys (for age and OpenPGP), or credentials (for any of the supported provider
implementations). The controller identifies the type of the entry by the suffix
@ -877,7 +900,7 @@ of the key (e.g. `.agekey`), or a fixed key (e.g. `sops.vault-token`).
apiVersion: v1
kind: Secret
metadata:
name: sops-keys
name: sops-keys-and-credentials
namespace: default
data:
# Exemplary age private key
@ -934,9 +957,9 @@ metadata:
namespace: default
data:
sops.aws-kms: |
aws_access_key_id: some-access-key-id
aws_secret_access_key: some-aws-secret-access-key
aws_session_token: some-aws-session-token # this field is optional
aws_access_key_id: some-access-key-id
aws_secret_access_key: some-aws-secret-access-key
aws_session_token: some-aws-session-token # this field is optional
```
#### Azure Key Vault Secret entry
@ -1405,6 +1428,8 @@ it is possible to specify global decryption settings on the
kustomize-controller Pod. When the controller fails to find credentials on the
Kustomization object itself, it will fall back to these defaults.
See also the [workload identity](/flux/installation/configuration/workload-identity/) docs.
#### AWS KMS
While making use of the [IAM OIDC provider](https://eksctl.io/usage/iamserviceaccounts/)

279
go.mod
View File

@ -1,6 +1,6 @@
module github.com/fluxcd/kustomize-controller
go 1.23.0
go 1.24.0
replace github.com/fluxcd/kustomize-controller/api => ./api
@ -9,149 +9,154 @@ replace github.com/fluxcd/kustomize-controller/api => ./api
replace github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be
require (
cloud.google.com/go/kms v1.21.2
filippo.io/age v1.2.1
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1
github.com/aws/aws-sdk-go-v2/credentials v1.17.57
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0
github.com/aws/aws-sdk-go-v2 v1.36.3
github.com/aws/aws-sdk-go-v2/credentials v1.17.67
github.com/cyphar/filepath-securejoin v0.4.1
github.com/dimchansky/utfbom v1.1.1
github.com/fluxcd/cli-utils v0.36.0-flux.12
github.com/fluxcd/kustomize-controller/api v1.5.0
github.com/fluxcd/pkg/apis/acl v0.6.0
github.com/fluxcd/pkg/apis/event v0.16.0
github.com/fluxcd/pkg/apis/kustomize v1.9.0
github.com/fluxcd/pkg/apis/meta v1.10.0
github.com/fluxcd/pkg/http/fetch v0.15.0
github.com/fluxcd/pkg/kustomize v1.16.0
github.com/fluxcd/pkg/runtime v0.53.1
github.com/fluxcd/pkg/ssa v0.45.1
github.com/fluxcd/pkg/tar v0.11.0
github.com/fluxcd/pkg/testserver v0.10.0
github.com/fluxcd/source-controller/api v1.5.0
github.com/getsops/sops/v3 v3.9.4
github.com/hashicorp/vault/api v1.15.0
github.com/onsi/gomega v1.36.2
github.com/fluxcd/cli-utils v0.36.0-flux.13
github.com/fluxcd/kustomize-controller/api v1.6.0
github.com/fluxcd/pkg/apis/acl v0.7.0
github.com/fluxcd/pkg/apis/event v0.17.0
github.com/fluxcd/pkg/apis/kustomize v1.10.0
github.com/fluxcd/pkg/apis/meta v1.12.0
github.com/fluxcd/pkg/auth v0.16.0
github.com/fluxcd/pkg/cache v0.9.0
github.com/fluxcd/pkg/http/fetch v0.16.0
github.com/fluxcd/pkg/kustomize v1.18.0
github.com/fluxcd/pkg/runtime v0.60.0
github.com/fluxcd/pkg/ssa v0.49.0
github.com/fluxcd/pkg/tar v0.12.0
github.com/fluxcd/pkg/testserver v0.11.0
github.com/fluxcd/source-controller/api v1.6.0
github.com/getsops/sops/v3 v3.10.2
github.com/hashicorp/vault/api v1.16.0
github.com/onsi/gomega v1.37.0
github.com/opencontainers/go-digest v1.0.0
github.com/ory/dockertest/v3 v3.11.0
github.com/ory/dockertest/v3 v3.12.0
github.com/spf13/pflag v1.0.6
golang.org/x/net v0.35.0
k8s.io/api v0.32.1
k8s.io/apimachinery v0.32.1
k8s.io/client-go v0.32.1
k8s.io/utils v0.0.0-20241210054802-24370beab758
sigs.k8s.io/controller-runtime v0.20.1
golang.org/x/net v0.40.0
golang.org/x/oauth2 v0.30.0
k8s.io/api v0.33.0
k8s.io/apimachinery v0.33.0
k8s.io/client-go v0.33.0
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e
sigs.k8s.io/controller-runtime v0.21.0
sigs.k8s.io/kustomize/api v0.19.0
sigs.k8s.io/yaml v1.4.0
sigs.k8s.io/yaml v1.5.0
)
// Pin kustomize to v5.6.0
// Pin kustomize to v5.7.0
replace (
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.19.0
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.19.0
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.20.0
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.20.0
)
// Fix CVE-2022-28948
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
require (
cel.dev/expr v0.19.1 // indirect
cloud.google.com/go v0.117.0 // indirect
cloud.google.com/go/auth v0.14.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
cel.dev/expr v0.22.1 // indirect
cloud.google.com/go v0.120.1 // indirect
cloud.google.com/go/auth v0.16.1 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.6.0 // indirect
cloud.google.com/go/iam v1.3.0 // indirect
cloud.google.com/go/kms v1.20.5 // indirect
cloud.google.com/go/longrunning v0.6.3 // indirect
cloud.google.com/go/monitoring v1.22.0 // indirect
cloud.google.com/go/storage v1.50.0 // indirect
cloud.google.com/go/iam v1.5.2 // indirect
cloud.google.com/go/longrunning v0.6.7 // indirect
cloud.google.com/go/monitoring v1.24.2 // indirect
cloud.google.com/go/storage v1.51.0 // indirect
dario.cat/mergo v1.0.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/ProtonMail/go-crypto v1.1.5 // indirect
github.com/ProtonMail/go-crypto v1.2.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.36.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.1 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 // indirect
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.53 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.28 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.5.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.9 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.37.13 // indirect
github.com/aws/aws-sdk-go-v2/service/s3 v1.74.0 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.12 // indirect
github.com/aws/smithy-go v1.22.2 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 // indirect
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
github.com/aws/smithy-go v1.22.3 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/carapace-sh/carapace-shlex v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cloudflare/circl v1.5.0 // indirect
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect
github.com/chai2010/gettext-go v1.0.3 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect
github.com/containerd/continuity v0.4.5 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v27.4.1+incompatible // indirect
github.com/docker/docker v27.4.1+incompatible // indirect
github.com/docker/cli v28.1.1+incompatible // indirect
github.com/docker/docker v28.1.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/envoyproxy/go-control-plane v0.13.1 // indirect
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fluxcd/pkg/envsubst v1.3.0 // indirect
github.com/fluxcd/pkg/sourceignore v0.11.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/fluxcd/pkg/envsubst v1.4.0 // indirect
github.com/fluxcd/pkg/sourceignore v0.12.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-git/go-git/v5 v5.13.2 // indirect
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
github.com/go-git/go-git/v5 v5.16.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/cel-go v0.23.1 // indirect
github.com/google/cel-go v0.23.2 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-containerregistry v0.20.3 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
@ -159,7 +164,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
@ -167,41 +172,41 @@ require (
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/sys/user v0.3.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest/blake3 v0.0.0-20240426182413-22b78e47854a // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opencontainers/runc v1.2.3 // indirect
github.com/opencontainers/go-digest/blake3 v0.0.0-20250116041648-1e56c6daea3b // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runc v1.2.6 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.63.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/cobra v1.9.1 // indirect
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/urfave/cli v1.22.16 // indirect
github.com/x448/float16 v0.8.4 // indirect
@ -210,45 +215,47 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
github.com/zeebo/errs v1.4.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.33.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.33.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.3 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/term v0.29.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/time v0.9.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/api v0.218.0 // indirect
google.golang.org/genproto v0.0.0-20241223144023-3abc09e42ca8 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241223144023-3abc09e42ca8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/grpc v1.70.0 // indirect
google.golang.org/protobuf v1.36.4 // indirect
golang.org/x/sync v0.14.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.11.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/api v0.230.0 // indirect
google.golang.org/genproto v0.0.0-20250425173222-7b384671a197 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197 // indirect
google.golang.org/grpc v1.72.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.32.1 // indirect
k8s.io/cli-runtime v0.32.1 // indirect
k8s.io/component-base v0.32.1 // indirect
k8s.io/apiextensions-apiserver v0.33.0 // indirect
k8s.io/cli-runtime v0.33.0 // indirect
k8s.io/component-base v0.33.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
k8s.io/kubectl v0.32.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/kubectl v0.33.0 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.20.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
)

593
go.sum
View File

@ -1,29 +1,29 @@
c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0=
c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w=
cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4=
cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
cloud.google.com/go v0.117.0 h1:Z5TNFfQxj7WG2FgOGX1ekC5RiXrYgms6QscOm32M/4s=
cloud.google.com/go v0.117.0/go.mod h1:ZbwhVTb1DBGt2Iwb3tNO6SEK4q+cplHZmLWH+DelYYc=
cloud.google.com/go/auth v0.14.0 h1:A5C4dKV/Spdvxcl0ggWwWEzzP7AZMJSEIgrkngwhGYM=
cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A=
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc=
cel.dev/expr v0.22.1 h1:xoFEsNh972Yzey8N9TCPx2nDvMN7TMhQEzxLuj/iRrI=
cel.dev/expr v0.22.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
cloud.google.com/go v0.120.1 h1:Z+5V7yd383+9617XDCyszmK5E4wJRJL+tquMfDj9hLM=
cloud.google.com/go v0.120.1/go.mod h1:56Vs7sf/i2jYM6ZL9NYlC82r04PThNcPS5YgFmb0rp8=
cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU=
cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
cloud.google.com/go/iam v1.3.0 h1:4Wo2qTaGKFtajbLpF6I4mywg900u3TLlHDb6mriLDPU=
cloud.google.com/go/iam v1.3.0/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY=
cloud.google.com/go/kms v1.20.5 h1:aQQ8esAIVZ1atdJRxihhdxGQ64/zEbJoJnCz/ydSmKg=
cloud.google.com/go/kms v1.20.5/go.mod h1:C5A8M1sv2YWYy1AE6iSrnddSG9lRGdJq5XEdBy28Lmw=
cloud.google.com/go/logging v1.12.0 h1:ex1igYcGFd4S/RZWOCU51StlIEuey5bjqwH9ZYjHibk=
cloud.google.com/go/logging v1.12.0/go.mod h1:wwYBt5HlYP1InnrtYI0wtwttpVU1rifnMT7RejksUAM=
cloud.google.com/go/longrunning v0.6.3 h1:A2q2vuyXysRcwzqDpMMLSI6mb6o39miS52UEG/Rd2ng=
cloud.google.com/go/longrunning v0.6.3/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI=
cloud.google.com/go/monitoring v1.22.0 h1:mQ0040B7dpuRq1+4YiQD43M2vW9HgoVxY98xhqGT+YI=
cloud.google.com/go/monitoring v1.22.0/go.mod h1:hS3pXvaG8KgWTSz+dAdyzPrGUYmi2Q+WFX8g2hqVEZU=
cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs=
cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY=
cloud.google.com/go/trace v1.11.2 h1:4ZmaBdL8Ng/ajrgKqY5jfvzqMXbrDcBsUGXOT9aqTtI=
cloud.google.com/go/trace v1.11.2/go.mod h1:bn7OwXd4pd5rFuAnTrzBuoZ4ax2XQeG3qNgYmfCy0Io=
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
cloud.google.com/go/kms v1.21.2 h1:c/PRUSMNQ8zXrc1sdAUnsenWWaNXN+PzTXfXOcSFdoE=
cloud.google.com/go/kms v1.21.2/go.mod h1:8wkMtHV/9Z8mLXEXr1GK7xPSBdi6knuLXIhqjuWcI6w=
cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM=
cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U=
cloud.google.com/go/storage v1.51.0 h1:ZVZ11zCiD7b3k+cH5lQs/qcNaoSz3U9I0jgwVzqDlCw=
cloud.google.com/go/storage v1.51.0/go.mod h1:YEJfu/Ki3i5oHC/7jyTgsGZwdQ8P9hqMqvpi5kRKGgc=
cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4=
cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI=
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o=
@ -32,106 +32,109 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1 h1:1mvYtZfWQAnwNah/C+Z+Jb9rQH95LPE2vlmMuWAHJk8=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1/go.mod h1:75I/mXtme1JyWFtz8GocPHVFyH421IBoZErnO16dd0k=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.1 h1:Bk5uOhSAenHyR5P61D/NzeQCv+4fEVV8mOkJ82NqpWw=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.1/go.mod h1:QZ4pw3or1WPmRBxf0cHd1tknzrT54WPBOQoGutCPvSU=
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/security/keyvault/azkeys v1.3.0 h1:7rKG7UmnrxX4N53TFhkYqjc+kVUZuw0fL8I3Fh+Ld9E=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.0/go.mod h1:Wjo+24QJVhhl/L7jy6w9yzFF2yDOf3cKECAa8ecf9vE=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.0 h1:eXnN9kaS8TiDwXjoie3hMRLuwdUBUMW9KRgOqB3mCaw=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.0/go.mod h1:XIpam8wumeZ5rVMuhdDQLMfIPDf1WO3IzrCRO3e3e3o=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0/go.mod h1:kUjrAo8bgEwLeZ/CmHqNl3Z/kPm7y6FKfxxK0izYUg4=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ=
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 h1:o90wcURuxekmXrtxmYWTyNla0+ZEHhud6DI1ZTxd1vI=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0/go.mod h1:6fTWu4m3jocfUZLYF5KsZC1TUfRvEjs7lM4crme/irw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.49.0 h1:jJKWl98inONJAr/IZrdFQUWcwUO95DLY1XMD1ZIut+g=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.49.0/go.mod h1:l2fIqmwB+FKSfvn3bAD/0i+AXAxhIZjTK2svT/mgUXs=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 h1:GYUJLfvd++4DMuMhCFLgLXvFwofIxh/qOwoGuS/LTew=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0/go.mod h1:wRbFgBQUVm1YXrvWKofAEmq9HNJTDphbAaJSSX01KUI=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go-v2 v1.36.0 h1:b1wM5CcE65Ujwn565qcwgtOTT1aT4ADOHHgglKjG7fk=
github.com/aws/aws-sdk-go-v2 v1.36.0/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
github.com/aws/aws-sdk-go-v2/config v1.29.1 h1:JZhGawAyZ/EuJeBtbQYnaoftczcb2drR2Iq36Wgz4sQ=
github.com/aws/aws-sdk-go-v2/config v1.29.1/go.mod h1:7bR2YD5euaxBhzt2y/oDkt3uNRb6tjFp98GlTFueRwk=
github.com/aws/aws-sdk-go-v2/credentials v1.17.57 h1:kFQDsbdBAR3GZsB8xA+51ptEnq9TIj3tS4MuP5b+TcQ=
github.com/aws/aws-sdk-go-v2/credentials v1.17.57/go.mod h1:2kerxPUUbTagAr/kkaHiqvj/bcYHzi2qiJS/ZinllU0=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 h1:7lOW8NUwE9UZekS1DYoiPdVAqZ6A+LheHWb+mHbNOq8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27/go.mod h1:w1BASFIPOPUae7AgaH4SbjNbfdkxuggLyGfNFTn8ITY=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.53 h1:3jYpOndmkKtmlPOhMNIV7Q92GD61x/KNjmxUcB95btw=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.53/go.mod h1:+s7tPUl4uy7FMpT5qnjkY5YJNuKU2HZL6trkYxQNtb4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 h1:lWm9ucLSRFiI4dQQafLrEOmEDGry3Swrz0BIRdiHJqQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31/go.mod h1:Huu6GG0YTfbPphQkDSo4dEGmQRTKb9k9G7RdtyQWxuI=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 h1:ACxDklUKKXb48+eg5ROZXi1vDgfMyfIA/WyvqHcHI0o=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31/go.mod h1:yadnfsDwqXeVaohbGc/RaD287PuyRw2wugkh5ZL2J6k=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.28 h1:7kpeALOUeThs2kEjlAxlADAVfxKmkYAedlpZ3kdoSJ4=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.28/go.mod h1:pyaOYEdp1MJWgtXLy6q80r3DhsVdOIOZNB9hdTcJIvI=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.5.2 h1:e6um6+DWYQP1XCa+E9YVtG/9v1qk5lyAOelMOVwSyO8=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.5.2/go.mod h1:dIW8puxSbYLSPv/ju0d9A3CpwXdtqvJtYKDMVmPLOWE=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 h1:O+8vD2rGjfihBewr5bT+QUfYUHIxCVgG61LHoT59shM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12/go.mod h1:usVdWJaosa66NMvmCrr08NcWDBRv4E6+YFG2pUdw1Lk=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.9 h1:2aInXbh02XsbO0KobPGMNXyv2QP73VDKsWPNJARj/+4=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.9/go.mod h1:dgXS1i+HgWnYkPXqNoPIPKeUsUUYHaUbThC90aDnNiE=
github.com/aws/aws-sdk-go-v2/service/kms v1.37.13 h1:JJHYuosiaMHr9V8m+v6UPmM7ZWHP+l8cv/xEG9OQTuE=
github.com/aws/aws-sdk-go-v2/service/kms v1.37.13/go.mod h1:TTGECZ6vGfx8k/pmzQKokSJy7ux2PJID4r96QCh5L0A=
github.com/aws/aws-sdk-go-v2/service/s3 v1.74.0 h1:ncCHiFU9Eq4qnKCNlzMZXfFmvb9R8OVNfU8SFOskxdI=
github.com/aws/aws-sdk-go-v2/service/s3 v1.74.0/go.mod h1:jGJ/v7FIi7Ys9t54tmEFnrxuaWeJLpwNgKp2DXAVhOU=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 h1:c5WJ3iHz7rLIgArznb3JCSQT3uUMiz9DLZhIX+1G8ok=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.14/go.mod h1:+JJQTxB6N4niArC14YNtxcQtwEqzS3o9Z32n7q33Rfs=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 h1:f1L/JtUkVODD+k1+IiSJUUv8A++2qVr+Xvb3xWXETMU=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13/go.mod h1:tvqlFoja8/s0o+UruA1Nrezo/df0PzdunMDDurUfg6U=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.12 h1:fqg6c1KVrc3SYWma/egWue5rKI4G2+M4wMQN2JosNAA=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.12/go.mod h1:7Yn+p66q/jt38qMoVfNvjbm3D89mGBnkwDcijgtih8w=
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14=
github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM=
github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 h1:PcKMOZfp+kNtJTw2HF2op6SjDvwPBYRvz0Y24PQLUR4=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72/go.mod h1:vq7/m7dahFXcdzWVOvvjasDI9RcsD3RsTfHmDundJYg=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs=
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 h1:YyH8Hk73bYzdbvf6S8NF5z/fb/1stpiMnFSfL6jSfRA=
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3/go.mod h1:iQ1skgw1XRK+6Lgkb0I9ODatAP72WoTILh0zXQ5DtbU=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 h1:lguz0bmOoGzozP9XfRJR1QIayEYo+2vP/No3OfLF0pU=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA=
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 h1:RivOtUH3eEu6SWnUMFHKAW4MqDOzWn1vGQ3S38Y5QMg=
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3/go.mod h1:cQn6tAF77Di6m4huxovNM7NVAozWTZLsDRp9t8Z/WYk=
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 h1:tWUG+4wZqdMl/znThEk9tcCy8tTMxq8dW0JTgamohrY=
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2/go.mod h1:U5SNqwhXB3Xe6F47kXvWihPl/ilGaEDe8HD/50Z9wxc=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=
github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
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/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
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/carapace-sh/carapace-shlex v1.0.1 h1:ww0JCgWpOVuqWG7k3724pJ18Lq8gh5pHQs9j3ojUs1c=
github.com/carapace-sh/carapace-shlex v1.0.1/go.mod h1:lJ4ZsdxytE0wHJ8Ta9S7Qq0XpjgjU0mdfCqiI2FHx7M=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80=
github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k=
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
@ -147,20 +150,26 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/docker/cli v27.4.1+incompatible h1:VzPiUlRJ/xh+otB75gva3r05isHMo5wXDfPRi5/b4hI=
github.com/docker/cli v27.4.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v27.4.1+incompatible h1:ZJvcY7gfwHn1JF48PfbyXg7Jyt9ZCWDW+GGXOIxEwp4=
github.com/docker/docker v27.4.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k=
github.com/docker/cli v28.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v28.1.1+incompatible h1:49M11BFLsVO1gxY9UX9p/zwkE/rswggs8AdFmXQw51I=
github.com/docker/docker v28.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=
github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
@ -171,52 +180,56 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fluxcd/cli-utils v0.36.0-flux.12 h1:8cD6SmaKa/lGo0KCu0XWiGrXJMLMBQwSsnoP0cG+Gjw=
github.com/fluxcd/cli-utils v0.36.0-flux.12/go.mod h1:Nb/zMqsJAzjz4/HIsEc2LTqxC6eC0rV26t4hkJT/F9o=
github.com/fluxcd/pkg/apis/acl v0.6.0 h1:rllf5uQLzTow81ZCslkQ6LPpDNqVQr6/fWaNksdUEtc=
github.com/fluxcd/pkg/apis/acl v0.6.0/go.mod h1:IVDZx3MAoDWjlLrJHMF9Z27huFuXAEQlnbWw0M6EcTs=
github.com/fluxcd/pkg/apis/event v0.16.0 h1:ffKc/3erowPnh72lFszz7sPQhLZ7bhqNrq+pu1Pb+JE=
github.com/fluxcd/pkg/apis/event v0.16.0/go.mod h1:D/QQi5lHT9/Ur3OMFLJO71D4KDQHbJ5s8dQV3h1ZAT0=
github.com/fluxcd/pkg/apis/kustomize v1.9.0 h1:SJpT1CK58AnTvCpDKeGfMNA0Xud/4VReZNvPe8XkTxo=
github.com/fluxcd/pkg/apis/kustomize v1.9.0/go.mod h1:AZl2GU03oPVue6SUivdiIYd/3mvF94j7t1G2JO26d4s=
github.com/fluxcd/pkg/apis/meta v1.10.0 h1:rqbAuyl5ug7A5jjRf/rNwBXmNl6tJ9wG2iIsriwnQUk=
github.com/fluxcd/pkg/apis/meta v1.10.0/go.mod h1:n7NstXHDaleAUMajcXTVkhz0MYkvEXy1C/eLI/t1xoI=
github.com/fluxcd/pkg/envsubst v1.3.0 h1:84Ain+8EBvyzu6y0FsKRwNsvaSiKuqhTqeh/4yoGFFU=
github.com/fluxcd/pkg/envsubst v1.3.0/go.mod h1:lz6HvqDnxbX0sIqjr1fxw0oTGYACLVFcOE/srKS0VQQ=
github.com/fluxcd/pkg/http/fetch v0.15.0 h1:AJ1JuE2asuK4QMfbHjxctFURke5FvZtyljjI1Qv4ArQ=
github.com/fluxcd/pkg/http/fetch v0.15.0/go.mod h1:feTESfETKU14jq+e/Ce8QnMBTCh9O79bLMSMe5t55fQ=
github.com/fluxcd/pkg/kustomize v1.16.0 h1:UBOeIvkrC6y4owYs7vZwG5PUVFeqnRoDFN9eaNhuNPI=
github.com/fluxcd/pkg/kustomize v1.16.0/go.mod h1:6yQkAZaG+w3nXY30LbyWRYHimjRcLRwlYkrwG0ygMSI=
github.com/fluxcd/pkg/runtime v0.53.1 h1:S+QRSoiU+LH1sTvJLNvT1x3E5hBq/sjOsRHazA7OqTo=
github.com/fluxcd/pkg/runtime v0.53.1/go.mod h1:8vkIhS1AhkmjC98LRm5xM+CRG5KySFTXpJWk+ZdtT4I=
github.com/fluxcd/pkg/sourceignore v0.11.0 h1:xzpYmc5/t/Ck+/DkJSX3r+VbahDRIAn5kbv04fynWUo=
github.com/fluxcd/pkg/sourceignore v0.11.0/go.mod h1:ri2FvlzX8ep2iszOK5gF/riYq2TNgpVvsfJ2QY0dLWI=
github.com/fluxcd/pkg/ssa v0.45.1 h1:ISl84TJwRP/GuZXrKiR9Tf8JOnG5XFgtjcYoR4XQYf4=
github.com/fluxcd/pkg/ssa v0.45.1/go.mod h1:8Anf7XVZ0zxOve7HXbDaW1s0gfmP95ksJBlKfDYinhQ=
github.com/fluxcd/pkg/tar v0.11.0 h1:pjf/rzr6HNAPiuxT59mtba9tfBtdNiSQ/UqduG8vZ2I=
github.com/fluxcd/pkg/tar v0.11.0/go.mod h1:+kiP25NqibWMpFWgizyPEMqnMJIux7bCgEy+4pfxyI4=
github.com/fluxcd/pkg/testserver v0.10.0 h1:g5l6mX9GndovWXCTW9xCPbL6YQYgphwe4Ee6cuBmLcA=
github.com/fluxcd/pkg/testserver v0.10.0/go.mod h1:dqpWALgSYdcmPS9OXq165s4OjUexVysl++EZJ8uZVkw=
github.com/fluxcd/source-controller/api v1.5.0 h1:caSR+u/r2Vh0jq/0pNR0r1zLxyvgatWuGSV2mxgTB/I=
github.com/fluxcd/source-controller/api v1.5.0/go.mod h1:OZPuHMlLH2E2mnj6Q5DLkWfUOmJ20zA1LIvUVfNsYl8=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/fluxcd/cli-utils v0.36.0-flux.13 h1:2X5yjz/rk9mg7+bMFBDZKGKzeZpAmY2s6iwbNZz7OzM=
github.com/fluxcd/cli-utils v0.36.0-flux.13/go.mod h1:b2iSoIeDTtjfCB0IKtGgqlhhvWa1oux3e90CjOf81oA=
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0=
github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ=
github.com/fluxcd/pkg/apis/event v0.17.0 h1:foEINE++pCJlWVhWjYDXfkVmGKu8mQ4BDBlbYi5NU7M=
github.com/fluxcd/pkg/apis/event v0.17.0/go.mod h1:0fLhLFiHlRTDKPDXdRnv+tS7mCMIQ0fJxnEfmvGM/5A=
github.com/fluxcd/pkg/apis/kustomize v1.10.0 h1:47EeSzkQvlQZdH92vHMe2lK2iR8aOSEJq95avw5idts=
github.com/fluxcd/pkg/apis/kustomize v1.10.0/go.mod h1:UsqMV4sqNa1Yg0pmTsdkHRJr7bafBOENIJoAN+3ezaQ=
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg=
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
github.com/fluxcd/pkg/auth v0.16.0 h1:YEjSaNqlpYoXfoFAGhU/Z8y0322nGsT24W6zCh+sbGw=
github.com/fluxcd/pkg/auth v0.16.0/go.mod h1:+BRnAO61Nr6fACEjJS6eNRdOk1nXhX/FCPylYn1ypNc=
github.com/fluxcd/pkg/cache v0.9.0 h1:EGKfOLMG3fOwWnH/4Axl5xd425mxoQbZzlZoLfd8PDk=
github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU=
github.com/fluxcd/pkg/envsubst v1.4.0 h1:pYsb6wrmXOSfHXuXQHaaBBMt3LumhgCb8SMdBNAwV/U=
github.com/fluxcd/pkg/envsubst v1.4.0/go.mod h1:zSDFO3Wawi+vI2NPxsMQp+EkIsz/85MNg/s1Wzmqt+s=
github.com/fluxcd/pkg/http/fetch v0.16.0 h1:XzhBTSK5HNdAPEnEGMJHwtoN2LfqQ9QFDsu3DGzl908=
github.com/fluxcd/pkg/http/fetch v0.16.0/go.mod h1:+A+yrOzwA5436ufD8NPeCCQFNzk4metoPUgRVCozvzw=
github.com/fluxcd/pkg/kustomize v1.18.0 h1:wWK+qYwmBmba3N3VAqZ9ijnfVGGaIjcaHWo033URZTw=
github.com/fluxcd/pkg/kustomize v1.18.0/go.mod h1:Ij9722MdWIE6B1EPg2ZJUf6npycgfRfN4Lohi7D/Kic=
github.com/fluxcd/pkg/runtime v0.60.0 h1:d++EkV3FlycB+bzakB5NumwY4J8xts8i7lbvD6jBLeU=
github.com/fluxcd/pkg/runtime v0.60.0/go.mod h1:UeU0/eZLErYC/1bTmgzBfNXhiHy9fuQzjfLK0HxRgxY=
github.com/fluxcd/pkg/sourceignore v0.12.0 h1:jCIe6d50rQ3wdXPF0+PhhqN0XrTRIq3upMomPelI8Mw=
github.com/fluxcd/pkg/sourceignore v0.12.0/go.mod h1:dc0zvkuXM5OgL/b3IkrVuwvPjj1zJn4NBUMH45uJ4Y0=
github.com/fluxcd/pkg/ssa v0.49.0 h1:3xBMxWQIpmKu+zUmyuKQ9M4f+ALhbMJIkiLXeGkhig4=
github.com/fluxcd/pkg/ssa v0.49.0/go.mod h1:T50TO0U2obLodZnrFgOrxollfBEy4V673OkM2aTUF1c=
github.com/fluxcd/pkg/tar v0.12.0 h1:og6F+ivnWNRbNJSq0ukCTVs7YrGIlzjxSVZU+E8NprM=
github.com/fluxcd/pkg/tar v0.12.0/go.mod h1:Ra5Cj++MD5iCy7bZGKJJX3GpOeMPv+ZDkPO9bBwpDeU=
github.com/fluxcd/pkg/testserver v0.11.0 h1:a/kxpFqv7XQxZjwVPP3voooRmSd/3ipLVolK0xUIxXQ=
github.com/fluxcd/pkg/testserver v0.11.0/go.mod h1:E8LAH1jW9uClFjTRN27Y/gCCSrzNVx1/w/0NxKuNcas=
github.com/fluxcd/source-controller/api v1.6.0 h1:IxfjUczJ2pzbXIef6iQ0RHEH4AYA9anJfTGK8dzwODM=
github.com/fluxcd/source-controller/api v1.6.0/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e h1:y/1nzrdF+RPds4lfoEpNhjfmzlgZtPqyO3jMzrqDQws=
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e/go.mod h1:awFzISqLJoZLm+i9QQ4SgMNHDqljH6jWV0B36V5MrUM=
github.com/getsops/sops/v3 v3.9.4 h1:f5JQRkXrK1SWM/D7HD8gCFLrUPZIEP+XUHs0byaNaqk=
github.com/getsops/sops/v3 v3.9.4/go.mod h1:zI9m7ji9gsegGA/4pWMT3EGkDdbeTiafgL9mAxz1weE=
github.com/getsops/sops/v3 v3.10.2 h1:7t7lBXFcXJPsDMrpYoI36r8xIhjWUmEc8Qdjuwyo+WY=
github.com/getsops/sops/v3 v3.10.2/go.mod h1:Dmtg1qKzFsAl+yqvMgjtnLGTC0l7RnSM6DDtFG7TEsk=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0=
github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A=
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ=
github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@ -224,12 +237,12 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
@ -240,40 +253,40 @@ github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIx
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
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=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/cel-go v0.23.1 h1:91ThhEZlBcE5rB2adBVXqvDoqdL8BG2oyhd0bK1I/r4=
github.com/google/cel-go v0.23.1/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo=
github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4=
github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
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-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI=
github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI=
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/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc=
github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0=
github.com/google/pprof v0.0.0-20250128161936-077ca0a936bf h1:BvBLUD2hkvLI3dJTJMiopAq8/wp43AAZKTP7qdpptbU=
github.com/google/pprof v0.0.0-20250128161936-077ca0a936bf/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 h1:Y9iQJfEqnN3/Nce9cOegemcy/9Ai5k3huT6E80F3zaw=
github.com/goware/prefixer v0.0.0-20160118172347-395022866408/go.mod h1:PE1ycukgRPJ7bJ9a1fdfQ9j8i/cEcRAoLZzbxYpNB/s=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
@ -291,16 +304,16 @@ github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISH
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 h1:iBt4Ew4XEGLfh6/bPk4rSYmuZJGizr6/x/AEizP0CQc=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8/go.mod h1:aiJI+PIApBRQG7FZTEBx5GiiX+HbOHilUdNxUZi4eV0=
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA=
github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8=
github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4=
github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@ -309,14 +322,14 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
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/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU=
github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k=
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.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -329,9 +342,8 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
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/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@ -344,10 +356,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -359,20 +371,20 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be h1:f2PlhC9pm5sqpBZFvnAoKj+KzXRzbjFMA+TqXfJdgho=
github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/go-digest/blake3 v0.0.0-20240426182413-22b78e47854a h1:xwooQrLddjfeKhucuLS4ElD3TtuuRwF8QWC9eHrnbxY=
github.com/opencontainers/go-digest/blake3 v0.0.0-20240426182413-22b78e47854a/go.mod h1:kqQaIc6bZstKgnGpL7GD5dWoLKbA6mH1Y9ULjGImBnM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/opencontainers/runc v1.2.3 h1:fxE7amCzfZflJO2lHXf4y/y8M1BoAqp+FVmG19oYB80=
github.com/opencontainers/runc v1.2.3/go.mod h1:nSxcWUydXrsBZVYNSkTjoQ/N6rcyTtn+1SD5D4+kRIM=
github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA=
github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI=
github.com/opencontainers/go-digest/blake3 v0.0.0-20250116041648-1e56c6daea3b h1:nAiL9bmUK4IzFrKoVMRykv0iYGdoit5vpbPaVCZ+fI4=
github.com/opencontainers/go-digest/blake3 v0.0.0-20250116041648-1e56c6daea3b/go.mod h1:kqQaIc6bZstKgnGpL7GD5dWoLKbA6mH1Y9ULjGImBnM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opencontainers/runc v1.2.6 h1:P7Hqg40bsMvQGCS4S7DJYhUZOISMLJOB2iGX5COWiPk=
github.com/opencontainers/runc v1.2.6/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4=
github.com/ory/dockertest/v3 v3.12.0 h1:3oV9d0sDzlSQfHtIaB5k6ghUCVMVLpAY8hwrqoCyRCw=
github.com/ory/dockertest/v3 v3.12.0/go.mod h1:aKNDTva3cp8dwOWwb9cWuX84aH5akkxXRvO7KCwWVjE=
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
@ -388,18 +400,18 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1
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/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
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.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
@ -408,11 +420,12 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
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/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=
github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -449,41 +462,47 @@ github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/detectors/gcp v1.33.0 h1:FVPoXEoILwgbZUu4X7YSgsESsAmGRgoYcnXkzgQPhP4=
go.opentelemetry.io/contrib/detectors/gcp v1.33.0/go.mod h1:ZHrLmr4ikK2AwRj9QL+c9s2SOlgoSRyMpNVzUj2fZqI=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA=
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM=
go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM=
go.opentelemetry.io/otel/sdk/metric v1.33.0 h1:Gs5VK9/WUJhNXZgn8MR6ITatvAmKeIuCtNbsP3JkNqU=
go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
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/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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@ -492,57 +511,56 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
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=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
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.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
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=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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.218.0 h1:x6JCjEWeZ9PFCRe9z0FBrNwj7pB7DOAqT35N+IPnAUA=
google.golang.org/api v0.218.0/go.mod h1:5VGHBAkxrA/8EFjLVEYmMUJ8/8+gWWQ3s4cFH0FxG2M=
google.golang.org/genproto v0.0.0-20241223144023-3abc09e42ca8 h1:e26eS1K69yxjjNNHYqjN49y95kcaQLJ3TL5h68dcA1E=
google.golang.org/genproto v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:i5btTErZyoKCCubju3HS5LVho4nZd3yFnEp6moqeUjE=
google.golang.org/genproto/googleapis/api v0.0.0-20241223144023-3abc09e42ca8 h1:st3LcW/BPi75W4q1jJTEor/QWwbNlPlDG0JTn6XhZu0=
google.golang.org/genproto/googleapis/api v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:klhJGKFyG8Tn50enBn7gizg4nXGXJ+jqEREdCWaPcV4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/api v0.230.0 h1:2u1hni3E+UXAXrONrrkfWpi/V6cyKVAbfGVeGtC3OxM=
google.golang.org/api v0.230.0/go.mod h1:aqvtoMk7YkiXx+6U12arQFExiRV9D/ekvMCwCd/TksQ=
google.golang.org/genproto v0.0.0-20250425173222-7b384671a197 h1:qWb9n6MA4nHA/g2varvEG/jTCs8zUuSa+5VqFgX2K+0=
google.golang.org/genproto v0.0.0-20250425173222-7b384671a197/go.mod h1:Cej/8iHf9mPl71o/a+R1rrvSFrAAVCUFX9s/sbNttBc=
google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197 h1:9DuBh3k1jUho2DHdxH+kbJwthIAq02vGvZNrD2ggF+Y=
google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197/go.mod h1:Cd8IzgPo5Akum2c9R6FsXNaZbH3Jpa2gpHlW89FqlyQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197 h1:29cjnHVylHwTzH66WfFZqgSQgnxzvWE+jvBwpZCLRxY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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=
@ -554,41 +572,44 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/cli-runtime v0.32.1 h1:19nwZPlYGJPUDbhAxDIS2/oydCikvKMHsxroKNGA2mM=
k8s.io/cli-runtime v0.32.1/go.mod h1:NJPbeadVFnV2E7B7vF+FvU09mpwYlZCu8PqjzfuOnkY=
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
k8s.io/component-base v0.32.1 h1:/5IfJ0dHIKBWysGV0yKTFfacZ5yNV1sulPh3ilJjRZk=
k8s.io/component-base v0.32.1/go.mod h1:j1iMMHi/sqAHeG5z+O9BFNCF698a1u0186zkjMZQ28w=
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs=
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc=
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/cli-runtime v0.33.0 h1:Lbl/pq/1o8BaIuyn+aVLdEPHVN665tBAXUePs8wjX7c=
k8s.io/cli-runtime v0.33.0/go.mod h1:QcA+r43HeUM9jXFJx7A+yiTPfCooau/iCcP1wQh4NFw=
k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98=
k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg=
k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk=
k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg=
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
k8s.io/kubectl v0.32.1 h1:/btLtXLQUU1rWx8AEvX9jrb9LaI6yeezt3sFALhB8M8=
k8s.io/kubectl v0.32.1/go.mod h1:sezNuyWi1STk4ZNPVRIFfgjqMI6XMf+oCVLjZen/pFQ=
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5ZtjZnHaE=
sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
k8s.io/kubectl v0.33.0 h1:HiRb1yqibBSCqic4pRZP+viiOBAnIdwYDpzUFejs07g=
k8s.io/kubectl v0.33.0/go.mod h1:gAlGBuS1Jq1fYZ9AjGWbI/5Vk3M/VW2DK4g10Fpyn/0=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o=
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA=
sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY=
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/kustomize/api v0.20.0 h1:xPLqcobHI0bThyRUteO+nCV8G4d1Rlo5HafO57VRcas=
sigs.k8s.io/kustomize/api v0.20.0/go.mod h1:F6CfaV27oevRCMJgehLqyX81dlUnRX/Fc13Uo7+OSo4=
sigs.k8s.io/kustomize/kyaml v0.20.0 h1:tT8KMKi4R3hCJ1+9HDdek2VoXpkerP92ZfF6fDgGw14=
sigs.k8s.io/kustomize/kyaml v0.20.0/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=

29
internal/cache/operations.go vendored Normal file
View File

@ -0,0 +1,29 @@
/*
Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package intcache
const (
OperationDecryptWithAWS = "decrypt_with_aws"
OperationDecryptWithAzure = "decrypt_with_azure"
OperationDecryptWithGCP = "decrypt_with_gcp"
)
var AllOperations = []string{
OperationDecryptWithAWS,
OperationDecryptWithAzure,
OperationDecryptWithGCP,
}

View File

@ -29,14 +29,16 @@ import (
"github.com/fluxcd/pkg/apis/kustomize"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/runtime/conditions"
"github.com/fluxcd/pkg/testserver"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/kustomize-controller/internal/decryptor"
)
func TestKustomizationReconciler_InvalidCELExpression(t *testing.T) {
func TestKustomizationReconciler_ConfigurationError(t *testing.T) {
g := NewWithT(t)
id := "invalid-config-" + randStringRunes(5)
revision := "v1.0.0"
@ -72,53 +74,143 @@ data: {}
err = applyGitRepository(repositoryName, artifact, revision)
g.Expect(err).NotTo(HaveOccurred())
kustomizationKey := types.NamespacedName{
Name: fmt.Sprintf("invalid-config-%s", randStringRunes(5)),
Namespace: id,
}
kustomization := &kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: kustomizationKey.Name,
Namespace: kustomizationKey.Namespace,
},
Spec: kustomizev1.KustomizationSpec{
Interval: metav1.Duration{Duration: 2 * time.Minute},
Path: "./",
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
Kind: sourcev1.GitRepositoryKind,
t.Run("invalid cel expression", func(t *testing.T) {
g := NewWithT(t)
kustomizationKey := types.NamespacedName{
Name: fmt.Sprintf("invalid-config-%s", randStringRunes(5)),
Namespace: id,
}
kustomization := &kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: kustomizationKey.Name,
Namespace: kustomizationKey.Namespace,
},
TargetNamespace: id,
Prune: true,
Timeout: &metav1.Duration{Duration: time.Second},
Wait: true,
HealthCheckExprs: []kustomize.CustomHealthCheck{{
APIVersion: "v1",
Kind: "ConfigMap",
HealthCheckExpressions: kustomize.HealthCheckExpressions{
InProgress: "foo.",
Current: "true",
Spec: kustomizev1.KustomizationSpec{
TargetNamespace: id,
Interval: metav1.Duration{Duration: 2 * time.Minute},
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
Kind: sourcev1.GitRepositoryKind,
},
}},
},
}
Prune: true,
Timeout: &metav1.Duration{Duration: time.Second},
Wait: true,
HealthCheckExprs: []kustomize.CustomHealthCheck{{
APIVersion: "v1",
Kind: "ConfigMap",
HealthCheckExpressions: kustomize.HealthCheckExpressions{
InProgress: "foo.",
Current: "true",
},
}},
},
}
err = k8sClient.Create(context.Background(), kustomization)
g.Expect(err).NotTo(HaveOccurred())
err = k8sClient.Create(context.Background(), kustomization)
g.Expect(err).NotTo(HaveOccurred())
g.Eventually(func() bool {
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
return conditions.IsFalse(resultK, meta.ReadyCondition)
}, timeout, time.Second).Should(BeTrue())
logStatus(t, resultK)
g.Eventually(func() bool {
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
return conditions.IsFalse(resultK, meta.ReadyCondition)
}, timeout, time.Second).Should(BeTrue())
g.Expect(resultK.Status.ObservedGeneration).To(Equal(resultK.GetGeneration()))
g.Expect(resultK.Status.ObservedGeneration).To(Equal(resultK.GetGeneration()))
g.Expect(conditions.IsTrue(resultK, meta.StalledCondition)).To(BeTrue())
for _, cond := range []string{meta.ReadyCondition, meta.StalledCondition} {
g.Expect(conditions.GetReason(resultK, cond)).To(Equal(meta.InvalidCELExpressionReason))
g.Expect(conditions.GetMessage(resultK, cond)).To(ContainSubstring(
"failed to create custom status reader for healthchecks[0]: failed to parse the expression InProgress: failed to parse the CEL expression 'foo.': ERROR: <input>:1:5: Syntax error: no viable alternative at input '.'"))
}
g.Expect(conditions.IsTrue(resultK, meta.StalledCondition)).To(BeTrue())
for _, cond := range []string{meta.ReadyCondition, meta.StalledCondition} {
g.Expect(conditions.GetReason(resultK, cond)).To(Equal(meta.InvalidCELExpressionReason))
g.Expect(conditions.GetMessage(resultK, cond)).To(ContainSubstring(
"failed to create custom status evaluator for healthchecks[0]: failed to parse the expression InProgress: failed to parse the CEL expression 'foo.': ERROR: <input>:1:5: Syntax error: no viable alternative at input '.'"))
}
})
t.Run("object level workload identity feature gate disabled", func(t *testing.T) {
g := NewWithT(t)
kustomizationKey := types.NamespacedName{
Name: fmt.Sprintf("invalid-config-%s", randStringRunes(5)),
Namespace: id,
}
kustomization := &kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: kustomizationKey.Name,
Namespace: kustomizationKey.Namespace,
},
Spec: kustomizev1.KustomizationSpec{
TargetNamespace: id,
Interval: metav1.Duration{Duration: 2 * time.Minute},
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
Kind: sourcev1.GitRepositoryKind,
},
Prune: true,
Decryption: &kustomizev1.Decryption{
Provider: decryptor.DecryptionProviderSOPS,
ServiceAccountName: "foo",
},
},
}
err = k8sClient.Create(context.Background(), kustomization)
g.Expect(err).NotTo(HaveOccurred())
g.Eventually(func() bool {
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
return conditions.IsFalse(resultK, meta.ReadyCondition)
}, timeout, time.Second).Should(BeTrue())
// In this case the controller does not update the observed generation
// because if the feature gate is enabled then the generation of the
// object can be properly observed.
g.Expect(resultK.Status.ObservedGeneration).To(Equal(int64(-1)))
g.Expect(conditions.IsTrue(resultK, meta.StalledCondition)).To(BeTrue())
for _, cond := range []string{meta.ReadyCondition, meta.StalledCondition} {
g.Expect(conditions.GetReason(resultK, cond)).To(Equal(meta.FeatureGateDisabledReason))
g.Expect(conditions.GetMessage(resultK, cond)).To(ContainSubstring(
"to use spec.decryption.serviceAccountName for decryption authentication please enable the ObjectLevelWorkloadIdentity feature gate in the controller"))
}
})
t.Run("object level workload identity feature gate enabled", func(t *testing.T) {
g := NewWithT(t)
t.Setenv(auth.EnvVarEnableObjectLevelWorkloadIdentity, "true")
kustomizationKey := types.NamespacedName{
Name: fmt.Sprintf("invalid-config-%s", randStringRunes(5)),
Namespace: id,
}
kustomization := &kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: kustomizationKey.Name,
Namespace: kustomizationKey.Namespace,
},
Spec: kustomizev1.KustomizationSpec{
TargetNamespace: id,
Interval: metav1.Duration{Duration: 2 * time.Minute},
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
Kind: sourcev1.GitRepositoryKind,
},
Prune: true,
Decryption: &kustomizev1.Decryption{
Provider: decryptor.DecryptionProviderSOPS,
ServiceAccountName: "foo",
},
},
}
err = k8sClient.Create(context.Background(), kustomization)
g.Expect(err).NotTo(HaveOccurred())
g.Eventually(func() bool {
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
return conditions.IsTrue(resultK, meta.ReadyCondition)
}, timeout, time.Second).Should(BeTrue())
})
}

View File

@ -27,8 +27,6 @@ import (
"time"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/fluxcd/pkg/ssa/normalize"
ssautil "github.com/fluxcd/pkg/ssa/utils"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
@ -49,10 +47,13 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling/engine"
"github.com/fluxcd/cli-utils/pkg/object"
apiacl "github.com/fluxcd/pkg/apis/acl"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/http/fetch"
generator "github.com/fluxcd/pkg/kustomize"
"github.com/fluxcd/pkg/runtime/acl"
@ -63,12 +64,15 @@ import (
"github.com/fluxcd/pkg/runtime/jitter"
"github.com/fluxcd/pkg/runtime/patch"
"github.com/fluxcd/pkg/runtime/predicates"
"github.com/fluxcd/pkg/runtime/statusreaders"
"github.com/fluxcd/pkg/ssa"
"github.com/fluxcd/pkg/ssa/normalize"
ssautil "github.com/fluxcd/pkg/ssa/utils"
"github.com/fluxcd/pkg/tar"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
intcache "github.com/fluxcd/kustomize-controller/internal/cache"
"github.com/fluxcd/kustomize-controller/internal/decryptor"
"github.com/fluxcd/kustomize-controller/internal/inventory"
)
@ -79,6 +83,7 @@ import (
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=buckets;ocirepositories;gitrepositories,verbs=get;list;watch
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=buckets/status;ocirepositories/status;gitrepositories/status,verbs=get
// +kubebuilder:rbac:groups="",resources=configmaps;secrets;serviceaccounts,verbs=get;list;watch
// +kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
// KustomizationReconciler reconciles a Kustomization object
@ -92,8 +97,7 @@ type KustomizationReconciler struct {
Mapper apimeta.RESTMapper
APIReader client.Reader
StatusPoller *polling.StatusPoller
PollingOpts polling.Options
ClusterReader engine.ClusterReaderFactory
ControllerName string
statusManager string
NoCrossNamespaceRefs bool
@ -105,6 +109,7 @@ type KustomizationReconciler struct {
DisallowedFieldManagers []string
StrictSubstitutions bool
GroupChangeLog bool
TokenCache *cache.TokenCache
}
// KustomizationReconcilerOptions contains options for the KustomizationReconciler.
@ -123,7 +128,7 @@ func (r *KustomizationReconciler) SetupWithManager(ctx context.Context, mgr ctrl
// Index the Kustomizations by the OCIRepository references they (may) point at.
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, ociRepositoryIndexKey,
r.indexBy(sourcev1b2.OCIRepositoryKind)); err != nil {
r.indexBy(sourcev1.OCIRepositoryKind)); err != nil {
return fmt.Errorf("failed setting index fields: %w", err)
}
@ -148,7 +153,7 @@ func (r *KustomizationReconciler) SetupWithManager(ctx context.Context, mgr ctrl
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
)).
Watches(
&sourcev1b2.OCIRepository{},
&sourcev1.OCIRepository{},
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(ociRepositoryIndexKey)),
builder.WithPredicates(SourceRevisionChangePredicate{}),
).
@ -190,6 +195,11 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
// Record Prometheus metrics.
r.Metrics.RecordDuration(ctx, obj, reconcileStart)
// Do not proceed if the Kustomization is suspended
if obj.Spec.Suspend {
return
}
// Log and emit success event.
if conditions.IsReady(obj) {
msg := fmt.Sprintf("Reconciliation finished in %s, next run in %s",
@ -224,7 +234,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}
// Configure custom health checks.
statusPoller, pollingOpts, err := r.getPollerAndOptions(ctx, obj)
statusReaders, err := cel.PollerWithCustomHealthChecks(ctx, obj.Spec.HealthCheckExprs)
if err != nil {
const msg = "Reconciliation failed terminally due to configuration error"
errMsg := fmt.Sprintf("%s: %v", msg, err)
@ -236,6 +246,18 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
return ctrl.Result{}, nil
}
// Check object-level workload identity feature gate.
if d := obj.Spec.Decryption; d != nil && d.ServiceAccountName != "" && !auth.IsObjectLevelWorkloadIdentityEnabled() {
const gate = auth.FeatureGateObjectLevelWorkloadIdentity
const msgFmt = "to use spec.decryption.serviceAccountName for decryption authentication please enable the %s feature gate in the controller"
msg := fmt.Sprintf(msgFmt, gate)
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FeatureGateDisabledReason, msgFmt, gate)
conditions.MarkStalled(obj, meta.FeatureGateDisabledReason, msgFmt, gate)
log.Error(auth.ErrObjectLevelWorkloadIdentityNotEnabled, msg)
r.event(obj, "", "", eventv1.EventSeverityError, msg, nil)
return ctrl.Result{}, nil
}
// Resolve the source reference and requeue the reconciliation if the source is not found.
artifactSource, err := r.getSource(ctx, obj)
if err != nil {
@ -281,7 +303,7 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}
// Reconcile the latest revision.
reconcileErr := r.reconcile(ctx, obj, artifactSource, patcher, statusPoller, pollingOpts)
reconcileErr := r.reconcile(ctx, obj, artifactSource, patcher, statusReaders)
// Requeue at the specified retry interval if the artifact tarball is not found.
if errors.Is(reconcileErr, fetch.ErrFileNotFound) {
@ -312,8 +334,7 @@ func (r *KustomizationReconciler) reconcile(
obj *kustomizev1.Kustomization,
src sourcev1.Source,
patcher *patch.SerialPatcher,
statusPoller *polling.StatusPoller,
pollingOpts polling.Options) error {
statusReaders []func(apimeta.RESTMapper) engine.StatusReader) error {
log := ctrl.LoggerFrom(ctx)
// Update status with the reconciliation progress.
@ -380,19 +401,32 @@ func (r *KustomizationReconciler) reconcile(
}
// Configure the Kubernetes client for impersonation.
impersonation := runtimeClient.NewImpersonator(
r.Client,
statusPoller,
pollingOpts,
obj.Spec.KubeConfig,
r.KubeConfigOpts,
r.DefaultServiceAccount,
obj.Spec.ServiceAccountName,
obj.GetNamespace(),
)
var impersonatorOpts []runtimeClient.ImpersonatorOption
var mustImpersonate bool
if r.DefaultServiceAccount != "" || obj.Spec.ServiceAccountName != "" {
mustImpersonate = true
impersonatorOpts = append(impersonatorOpts,
runtimeClient.WithServiceAccount(r.DefaultServiceAccount, obj.Spec.ServiceAccountName, obj.GetNamespace()))
}
if obj.Spec.KubeConfig != nil {
mustImpersonate = true
impersonatorOpts = append(impersonatorOpts,
runtimeClient.WithKubeConfig(obj.Spec.KubeConfig, r.KubeConfigOpts, obj.GetNamespace()))
}
if r.ClusterReader != nil || len(statusReaders) > 0 {
impersonatorOpts = append(impersonatorOpts,
runtimeClient.WithPolling(r.ClusterReader, statusReaders...))
}
impersonation := runtimeClient.NewImpersonator(r.Client, impersonatorOpts...)
// Create the Kubernetes client that runs under impersonation.
kubeClient, statusPoller, err := impersonation.GetClient(ctx)
var kubeClient client.Client
var statusPoller *polling.StatusPoller
if mustImpersonate {
kubeClient, statusPoller, err = impersonation.GetClient(ctx)
} else {
kubeClient, statusPoller = r.getClientAndPoller(statusReaders)
}
if err != nil {
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err)
return fmt.Errorf("failed to build kube client: %w", err)
@ -562,8 +596,8 @@ func (r *KustomizationReconciler) getSource(ctx context.Context,
}
switch obj.Spec.SourceRef.Kind {
case sourcev1b2.OCIRepositoryKind:
var repository sourcev1b2.OCIRepository
case sourcev1.OCIRepositoryKind:
var repository sourcev1.OCIRepository
err := r.Client.Get(ctx, namespacedName, &repository)
if err != nil {
if apierrors.IsNotFound(err) {
@ -608,17 +642,20 @@ func (r *KustomizationReconciler) generate(obj unstructured.Unstructured,
func (r *KustomizationReconciler) build(ctx context.Context,
obj *kustomizev1.Kustomization, u unstructured.Unstructured,
workDir, dirPath string) ([]byte, error) {
dec, cleanup, err := decryptor.NewTempDecryptor(workDir, r.Client, obj)
dec, cleanup, err := decryptor.NewTempDecryptor(workDir, r.Client, obj, r.TokenCache)
if err != nil {
return nil, err
}
defer cleanup()
// Import decryption keys
// Import keys and static credentials for decryption.
if err := dec.ImportKeys(ctx); err != nil {
return nil, err
}
// Set options for secret-less authentication with cloud providers for decryption.
dec.SetAuthOptions(ctx)
// Decrypt Kustomize EnvSources files before build
if err = dec.DecryptSources(dirPath); err != nil {
return nil, fmt.Errorf("error decrypting sources: %w", err)
@ -994,34 +1031,66 @@ func (r *KustomizationReconciler) prune(ctx context.Context,
return false, nil
}
// finalizerShouldDeleteResources determines if resources should be deleted
// based on the object's inventory and deletion policy.
// A suspended Kustomization or one without an inventory will not delete resources.
func finalizerShouldDeleteResources(obj *kustomizev1.Kustomization) bool {
if obj.GetDeletionPolicy() == kustomizev1.DeletionPolicyMirrorPrune {
return obj.Spec.Prune
if obj.Spec.Suspend {
return false
}
if obj.Status.Inventory == nil || len(obj.Status.Inventory.Entries) == 0 {
return false
}
switch obj.GetDeletionPolicy() {
case kustomizev1.DeletionPolicyMirrorPrune:
return obj.Spec.Prune
case kustomizev1.DeletionPolicyDelete:
return true
case kustomizev1.DeletionPolicyWaitForTermination:
return true
default:
return false
}
return obj.Spec.DeletionPolicy == kustomizev1.DeletionPolicyDelete
}
// finalize handles the finalization logic for a Kustomization resource during its deletion process.
// Managed resources are pruned based on the deletion policy and suspended state of the Kustomization.
// When the policy is set to WaitForTermination, the function blocks and waits for the resources
// to be terminated by the Kubernetes Garbage Collector for the specified timeout duration.
// If the service account used for impersonation is no longer available or if a timeout occurs
// while waiting for resources to be terminated, an error is logged and the finalizer is removed.
func (r *KustomizationReconciler) finalize(ctx context.Context,
obj *kustomizev1.Kustomization) (ctrl.Result, error) {
log := ctrl.LoggerFrom(ctx)
if finalizerShouldDeleteResources(obj) &&
!obj.Spec.Suspend &&
obj.Status.Inventory != nil &&
obj.Status.Inventory.Entries != nil {
if finalizerShouldDeleteResources(obj) {
objects, _ := inventory.List(obj.Status.Inventory)
impersonation := runtimeClient.NewImpersonator(
r.Client,
r.StatusPoller,
r.PollingOpts,
obj.Spec.KubeConfig,
r.KubeConfigOpts,
r.DefaultServiceAccount,
obj.Spec.ServiceAccountName,
obj.GetNamespace(),
)
var impersonatorOpts []runtimeClient.ImpersonatorOption
var mustImpersonate bool
if r.DefaultServiceAccount != "" || obj.Spec.ServiceAccountName != "" {
mustImpersonate = true
impersonatorOpts = append(impersonatorOpts,
runtimeClient.WithServiceAccount(r.DefaultServiceAccount, obj.Spec.ServiceAccountName, obj.GetNamespace()))
}
if obj.Spec.KubeConfig != nil {
mustImpersonate = true
impersonatorOpts = append(impersonatorOpts,
runtimeClient.WithKubeConfig(obj.Spec.KubeConfig, r.KubeConfigOpts, obj.GetNamespace()))
}
if r.ClusterReader != nil {
impersonatorOpts = append(impersonatorOpts, runtimeClient.WithPolling(r.ClusterReader))
}
impersonation := runtimeClient.NewImpersonator(r.Client, impersonatorOpts...)
if impersonation.CanImpersonate(ctx) {
kubeClient, _, err := impersonation.GetClient(ctx)
var kubeClient client.Client
var err error
if mustImpersonate {
kubeClient, _, err = impersonation.GetClient(ctx)
} else {
kubeClient = r.Client
}
if err != nil {
return ctrl.Result{}, err
}
@ -1048,7 +1117,21 @@ func (r *KustomizationReconciler) finalize(ctx context.Context,
}
if changeSet != nil && len(changeSet.Entries) > 0 {
// Emit event with the resources marked for deletion.
r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityInfo, changeSet.String(), nil)
// Wait for the resources marked for deletion to be terminated.
if obj.GetDeletionPolicy() == kustomizev1.DeletionPolicyWaitForTermination {
if err := resourceManager.WaitForSetTermination(changeSet, ssa.WaitOptions{
Interval: 2 * time.Second,
Timeout: obj.GetTimeout(),
}); err != nil {
// Emit an event and log the error if a timeout occurs.
msg := "failed to wait for resources termination"
log.Error(err, msg)
r.event(obj, obj.Status.LastAppliedRevision, obj.Status.LastAppliedOriginRevision, eventv1.EventSeverityError, msg, nil)
}
}
}
} else {
// when the account to impersonate is gone, log the stale objects and continue with the finalization
@ -1060,6 +1143,12 @@ func (r *KustomizationReconciler) finalize(ctx context.Context,
// Remove our finalizer from the list and update it
controllerutil.RemoveFinalizer(obj, kustomizev1.KustomizationFinalizer)
// Cleanup caches.
for _, op := range intcache.AllOperations {
r.TokenCache.DeleteEventsForObject(kustomizev1.KustomizationKind, obj.GetName(), obj.GetNamespace(), op)
}
// Stop reconciliation as the object is being deleted
return ctrl.Result{}, nil
}
@ -1150,6 +1239,29 @@ func (r *KustomizationReconciler) patch(ctx context.Context,
return nil
}
// getClientAndPoller creates a status poller with the custom status readers
// from CEL expressions and the custom job status reader, and returns the
// Kubernetes client of the controller and the status poller.
// Should be used for reconciliations that are not configured to use
// ServiceAccount impersonation or kubeconfig.
func (r *KustomizationReconciler) getClientAndPoller(
readerCtors []func(apimeta.RESTMapper) engine.StatusReader,
) (client.Client, *polling.StatusPoller) {
readers := make([]engine.StatusReader, 0, 1+len(readerCtors))
readers = append(readers, statusreaders.NewCustomJobStatusReader(r.Mapper))
for _, ctor := range readerCtors {
readers = append(readers, ctor(r.Mapper))
}
poller := polling.NewStatusPoller(r.Client, r.Mapper, polling.Options{
CustomStatusReaders: readers,
ClusterReaderFactory: r.ClusterReader,
})
return r.Client, poller
}
// getOriginRevision returns the origin revision of the source artifact,
// or the empty string if it's not present, or if the artifact itself
// is not present.
@ -1160,25 +1272,3 @@ func getOriginRevision(src sourcev1.Source) string {
}
return a.Metadata[OCIArtifactOriginRevisionAnnotation]
}
// getPollerAndOptions returns the status poller and polling options
// based on the healthcheck expressions defined in the Kustomization
// object spec.
func (r *KustomizationReconciler) getPollerAndOptions(ctx context.Context,
obj *kustomizev1.Kustomization) (*polling.StatusPoller, polling.Options, error) {
poller := r.StatusPoller
opts := r.PollingOpts
if hc := obj.Spec.HealthCheckExprs; len(hc) > 0 {
var err error
opts, err = cel.PollerWithCustomHealthChecks(ctx, opts, hc, r.Mapper)
if err != nil {
return nil, polling.Options{}, err
}
poller = polling.NewStatusPoller(r.Client, r.Mapper, opts)
}
return poller, opts, nil
}

View File

@ -48,6 +48,12 @@ func TestKustomizationReconciler_DeletionPolicyDelete(t *testing.T) {
deletionPolicy: kustomizev1.DeletionPolicyDelete,
wantDelete: true,
},
{
name: "should delete and wait when deletionPolicy overrides pruning disabled",
prune: false,
deletionPolicy: kustomizev1.DeletionPolicyWaitForTermination,
wantDelete: true,
},
{
name: "should delete when deletionPolicy mirrors prune and pruning enabled",
prune: true,
@ -131,6 +137,7 @@ data:
TargetNamespace: id,
Prune: tt.prune,
DeletionPolicy: tt.deletionPolicy,
Timeout: &metav1.Duration{Duration: 5 * time.Second},
},
}

View File

@ -0,0 +1,243 @@
/*
Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controller
import (
"context"
"testing"
"time"
"github.com/fluxcd/pkg/apis/kustomize"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/testserver"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
)
// TestKustomizationReconciler_MultiplePatchDelete tests the handling of multiple
// $patch: delete directives in strategic merge patches.
// This test ensures that the controller properly handles scenarios where multiple
// resources are deleted using a single patch specification.
func TestKustomizationReconciler_MultiplePatchDelete(t *testing.T) {
g := NewWithT(t)
id := "multi-patch-delete-" + randStringRunes(5)
revision := "v1.0.0"
err := createNamespace(id)
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
err = createKubeConfigSecret(id)
g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
// Create test files with multiple ConfigMaps
manifests := func(name string, data string) []testserver.File {
return []testserver.File{
{
Name: "configmaps.yaml",
Body: `---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm1
namespace: ` + name + `
data:
key: ` + data + `1
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm2
namespace: ` + name + `
data:
key: ` + data + `2
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm3
namespace: ` + name + `
data:
key: ` + data + `3
`,
},
}
}
artifact, err := testServer.ArtifactFromFiles(manifests(id, randStringRunes(5)))
g.Expect(err).NotTo(HaveOccurred())
repositoryName := types.NamespacedName{
Name: randStringRunes(5),
Namespace: id,
}
err = applyGitRepository(repositoryName, artifact, revision)
g.Expect(err).NotTo(HaveOccurred())
kustomizationKey := types.NamespacedName{
Name: "patch-delete-" + randStringRunes(5),
Namespace: id,
}
t.Run("multiple patch delete in single patch should work", func(t *testing.T) {
// This test verifies that multiple $patch: delete directives in a single patch work correctly
// Ref: https://github.com/fluxcd/kustomize-controller/issues/1306
kustomization := &kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: kustomizationKey.Name,
Namespace: kustomizationKey.Namespace,
},
Spec: kustomizev1.KustomizationSpec{
Interval: metav1.Duration{Duration: reconciliationInterval},
Path: "./",
KubeConfig: &meta.KubeConfigReference{
SecretRef: meta.SecretKeyReference{
Name: "kubeconfig",
},
},
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
Kind: sourcev1.GitRepositoryKind,
},
Prune: true,
Patches: []kustomize.Patch{
{
// Multiple $patch: delete in a single patch
Patch: `$patch: delete
apiVersion: v1
kind: ConfigMap
metadata:
name: cm1
namespace: ` + id + `
---
$patch: delete
apiVersion: v1
kind: ConfigMap
metadata:
name: cm2
namespace: ` + id + ``,
},
},
},
}
g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
// Wait for reconciliation and check that it succeeds without panic
g.Eventually(func() bool {
var obj kustomizev1.Kustomization
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), &obj)
return obj.Status.LastAppliedRevision == revision
}, timeout, time.Second).Should(BeTrue())
// Verify that only cm3 ConfigMap exists (cm1 and cm2 should be deleted)
var cm corev1.ConfigMap
err := k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm1", Namespace: id}, &cm)
g.Expect(err).To(HaveOccurred(), "cm1 should have been deleted")
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm2", Namespace: id}, &cm)
g.Expect(err).To(HaveOccurred(), "cm2 should have been deleted")
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm3", Namespace: id}, &cm)
g.Expect(err).NotTo(HaveOccurred(), "cm3 should still exist")
// Cleanup
g.Expect(k8sClient.Delete(context.Background(), kustomization)).To(Succeed())
g.Eventually(func() bool {
err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), kustomization)
return apierrors.IsNotFound(err)
}, timeout, time.Second).Should(BeTrue())
})
t.Run("multiple patch delete in separate patches should work", func(t *testing.T) {
// This test verifies that separate patches (which was previously a workaround) still work correctly
kustomizationSeparate := &kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: kustomizationKey.Name + "-separate",
Namespace: kustomizationKey.Namespace,
},
Spec: kustomizev1.KustomizationSpec{
Interval: metav1.Duration{Duration: reconciliationInterval},
Path: "./",
KubeConfig: &meta.KubeConfigReference{
SecretRef: meta.SecretKeyReference{
Name: "kubeconfig",
},
},
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
Kind: sourcev1.GitRepositoryKind,
},
Prune: true,
Patches: []kustomize.Patch{
{
Patch: `$patch: delete
apiVersion: v1
kind: ConfigMap
metadata:
name: cm1
namespace: ` + id + ``,
},
{
Patch: `$patch: delete
apiVersion: v1
kind: ConfigMap
metadata:
name: cm2
namespace: ` + id + ``,
},
},
},
}
g.Expect(k8sClient.Create(context.Background(), kustomizationSeparate)).To(Succeed())
// Wait for successful reconciliation
g.Eventually(func() bool {
var obj kustomizev1.Kustomization
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomizationSeparate), &obj)
return obj.Status.LastAppliedRevision == revision
}, timeout, time.Second).Should(BeTrue())
// Verify that only cm3 ConfigMap exists
var cm corev1.ConfigMap
err := k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm1", Namespace: id}, &cm)
g.Expect(err).To(HaveOccurred(), "cm1 should have been deleted")
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm2", Namespace: id}, &cm)
g.Expect(err).To(HaveOccurred(), "cm2 should have been deleted")
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm3", Namespace: id}, &cm)
g.Expect(err).NotTo(HaveOccurred(), "cm3 should still exist")
// Cleanup
g.Expect(k8sClient.Delete(context.Background(), kustomizationSeparate)).To(Succeed())
g.Eventually(func() bool {
err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomizationSeparate), kustomizationSeparate)
return apierrors.IsNotFound(err)
}, timeout, time.Second).Should(BeTrue())
})
}

View File

@ -22,9 +22,11 @@ import (
"testing"
"time"
runtimeClient "github.com/fluxcd/pkg/runtime/client"
. "github.com/onsi/gomega"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@ -279,7 +281,7 @@ parameters:
func TestKustomizationReconciler_WaitsForCustomHealthChecks(t *testing.T) {
g := NewWithT(t)
id := "wait-" + randStringRunes(5)
id := "cel-" + randStringRunes(5)
revision := "v1.0.0"
resultK := &kustomizev1.Kustomization{}
timeout := 60 * time.Second
@ -287,6 +289,9 @@ func TestKustomizationReconciler_WaitsForCustomHealthChecks(t *testing.T) {
err := createNamespace(id)
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
err = createKubeConfigSecret(id)
g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
manifests := func(name string) []testserver.File {
return []testserver.File{
{
@ -325,6 +330,11 @@ data: {}
Spec: kustomizev1.KustomizationSpec{
Interval: metav1.Duration{Duration: 2 * time.Minute},
Path: "./",
KubeConfig: &meta.KubeConfigReference{
SecretRef: meta.SecretKeyReference{
Name: "kubeconfig",
},
},
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
@ -360,3 +370,79 @@ data: {}
g.Expect(msg).
To(ContainSubstring("failed to evaluate the CEL expression 'has(data.foo.bar)': no such attribute(s): data.foo.bar"))
}
func TestKustomizationReconciler_RESTMapper(t *testing.T) {
g := NewWithT(t)
id := "rm-" + randStringRunes(5)
resultK := &kustomizev1.Kustomization{}
restMapper, err := runtimeClient.NewDynamicRESTMapper(testEnv.Config)
g.Expect(err).NotTo(HaveOccurred())
err = createNamespace(id)
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
err = createKubeConfigSecret(id)
g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
artifactName := "val-" + randStringRunes(5)
artifactChecksum, err := testServer.ArtifactFromDir("testdata/restmapper", artifactName)
g.Expect(err).ToNot(HaveOccurred())
repositoryName := types.NamespacedName{
Name: fmt.Sprintf("val-%s", randStringRunes(5)),
Namespace: id,
}
err = applyGitRepository(repositoryName, artifactName, "main/"+artifactChecksum)
g.Expect(err).NotTo(HaveOccurred())
kustomization := &kustomizev1.Kustomization{}
kustomization.Name = id
kustomization.Namespace = id
kustomization.Spec = kustomizev1.KustomizationSpec{
Interval: metav1.Duration{Duration: 10 * time.Minute},
Prune: true,
Path: "./",
Wait: true,
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
Kind: sourcev1.GitRepositoryKind,
},
KubeConfig: &meta.KubeConfigReference{
SecretRef: meta.SecretKeyReference{
Name: "kubeconfig",
},
},
}
g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
g.Eventually(func() bool {
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
return isReconcileSuccess(resultK) && resultK.Status.LastAttemptedRevision == "main/"+artifactChecksum
}, timeout, time.Second).Should(BeTrue())
t.Run("discovers newly registered CRD and preferred version", func(t *testing.T) {
mapping, err := restMapper.RESTMapping(schema.GroupKind{Kind: "ClusterCleanupPolicy", Group: "kyverno.io"})
g.Expect(err).NotTo(HaveOccurred())
g.Expect(mapping.Resource.Version).To(Equal("v2"))
})
t.Run("finalizes object", func(t *testing.T) {
g.Expect(k8sClient.Delete(context.Background(), resultK)).To(Succeed())
g.Eventually(func() bool {
err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
return apierrors.IsNotFound(err)
}, timeout, time.Second).Should(BeTrue())
})
t.Run("discovery fails for deleted CRD", func(t *testing.T) {
newMapper, err := runtimeClient.NewDynamicRESTMapper(testEnv.Config)
g.Expect(err).NotTo(HaveOccurred())
_, err = newMapper.RESTMapping(schema.GroupKind{Kind: "ClusterCleanupPolicy", Group: "kyverno.io"})
g.Expect(err).To(HaveOccurred())
})
}

View File

@ -47,7 +47,6 @@ import (
"github.com/fluxcd/pkg/runtime/testenv"
"github.com/fluxcd/pkg/testserver"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
)
@ -77,7 +76,6 @@ func runInContext(registerControllers func(*testenv.Environment), run func() int
var err error
utilruntime.Must(kustomizev1.AddToScheme(scheme.Scheme))
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
utilruntime.Must(sourcev1b2.AddToScheme(scheme.Scheme))
if debugMode {
controllerLog.SetLogger(zap.New(zap.WriteTo(os.Stderr), zap.UseDevMode(false)))

View File

@ -0,0 +1,22 @@
apiVersion: kyverno.io/v2
kind: ClusterCleanupPolicy
metadata:
name: test-cluster-cleanup-policy
spec:
conditions:
all:
- key: '{{ time_since('''', ''{{ target.metadata.creationTimestamp }}'', '''') }}'
operator: GreaterThan
value: 168h
match:
any:
- resources:
annotations:
openshift.io/description: review-*
openshift.io/requester: system:serviceaccount:*
kinds:
- Namespace
selector:
matchLabels:
test/project-name: "review"
schedule: '*/5 * * * *'

File diff suppressed because it is too large Load Diff

View File

@ -29,17 +29,25 @@ import (
"sync"
"time"
gcpkmsapi "cloud.google.com/go/kms/apiv1"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
awssdk "github.com/aws/aws-sdk-go-v2/aws"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/auth/aws"
"github.com/fluxcd/pkg/auth/azure"
"github.com/fluxcd/pkg/auth/gcp"
"github.com/fluxcd/pkg/cache"
"github.com/getsops/sops/v3"
"github.com/getsops/sops/v3/aes"
"github.com/getsops/sops/v3/age"
"github.com/getsops/sops/v3/azkv"
"github.com/getsops/sops/v3/cmd/sops/common"
"github.com/getsops/sops/v3/cmd/sops/formats"
"github.com/getsops/sops/v3/config"
"github.com/getsops/sops/v3/keyservice"
awskms "github.com/getsops/sops/v3/kms"
"github.com/getsops/sops/v3/pgp"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@ -51,6 +59,7 @@ import (
"sigs.k8s.io/yaml"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
intcache "github.com/fluxcd/kustomize-controller/internal/cache"
intawskms "github.com/fluxcd/kustomize-controller/internal/sops/awskms"
intazkv "github.com/fluxcd/kustomize-controller/internal/sops/azkv"
intkeyservice "github.com/fluxcd/kustomize-controller/internal/sops/keyservice"
@ -127,6 +136,8 @@ type Decryptor struct {
// injected into most resources, causing the integrity check to fail.
// Mostly kept around for feature completeness and documentation purposes.
checkSopsMac bool
// tokenCache is the cache for token credentials.
tokenCache *cache.TokenCache
// gnuPGHome is the absolute path of the GnuPG home directory used to
// decrypt PGP data. When empty, the systems' GnuPG keyring is used.
@ -137,15 +148,15 @@ type Decryptor struct {
// vaultToken is the Hashicorp Vault token used to authenticate towards
// any Vault server.
vaultToken string
// awsCredsProvider is the AWS credentials provider object used to authenticate
// awsCredentialsProvider is the AWS credentials provider object used to authenticate
// towards any AWS KMS.
awsCredsProvider *awskms.CredentialsProvider
// azureToken is the Azure credential token used to authenticate towards
awsCredentialsProvider func(region string) awssdk.CredentialsProvider
// azureTokenCredential is the Azure credential token used to authenticate towards
// any Azure Key Vault.
azureToken *azkv.TokenCredential
// gcpCredsJSON is the JSON credential file of the service account used to
// authenticate towards any GCP KMS.
gcpCredsJSON []byte
azureTokenCredential azcore.TokenCredential
// gcpTokenSource is the GCP token source used to authenticate towards
// any GCP KMS.
gcpTokenSource oauth2.TokenSource
// keyServices are the SOPS keyservice.KeyServiceClient's available to the
// decryptor.
@ -155,25 +166,28 @@ type Decryptor struct {
// NewDecryptor creates a new Decryptor for the given kustomization.
// gnuPGHome can be empty, in which case the systems' keyring is used.
func NewDecryptor(root string, client client.Client, kustomization *kustomizev1.Kustomization, maxFileSize int64, gnuPGHome string) *Decryptor {
func NewDecryptor(root string, client client.Client, kustomization *kustomizev1.Kustomization,
maxFileSize int64, gnuPGHome string, tokenCache *cache.TokenCache) *Decryptor {
return &Decryptor{
root: root,
client: client,
kustomization: kustomization,
maxFileSize: maxFileSize,
gnuPGHome: pgp.GnuPGHome(gnuPGHome),
tokenCache: tokenCache,
}
}
// NewTempDecryptor creates a new Decryptor, with a temporary GnuPG
// home directory to Decryptor.ImportKeys() into.
func NewTempDecryptor(root string, client client.Client, kustomization *kustomizev1.Kustomization) (*Decryptor, func(), error) {
func NewTempDecryptor(root string, client client.Client, kustomization *kustomizev1.Kustomization,
tokenCache *cache.TokenCache) (*Decryptor, func(), error) {
gnuPGHome, err := pgp.NewGnuPGHome()
if err != nil {
return nil, nil, fmt.Errorf("cannot create decryptor: %w", err)
}
cleanup := func() { _ = os.RemoveAll(gnuPGHome.String()) }
return NewDecryptor(root, client, kustomization, maxEncryptedFileSize, gnuPGHome.String()), cleanup, nil
return NewDecryptor(root, client, kustomization, maxEncryptedFileSize, gnuPGHome.String(), tokenCache), cleanup, nil
}
// IsEncryptedSecret checks if the given object is a Kubernetes Secret encrypted
@ -228,7 +242,6 @@ func (d *Decryptor) ImportKeys(ctx context.Context) error {
return fmt.Errorf("failed to import '%s' data from %s decryption Secret '%s': %w", name, provider, secretName, err)
}
case filepath.Ext(DecryptionVaultTokenFileName):
// Make sure we have the absolute name
if name == DecryptionVaultTokenFileName {
token := string(value)
token = strings.Trim(strings.TrimSpace(token), "\n")
@ -240,10 +253,9 @@ func (d *Decryptor) ImportKeys(ctx context.Context) error {
if err != nil {
return fmt.Errorf("failed to import '%s' data from %s decryption Secret '%s': %w", name, provider, secretName, err)
}
d.awsCredsProvider = awskms.NewCredentialsProvider(awsCreds)
d.awsCredentialsProvider = func(string) awssdk.CredentialsProvider { return awsCreds }
}
case filepath.Ext(DecryptionAzureAuthFile):
// Make sure we have the absolute name
if name == DecryptionAzureAuthFile {
conf := intazkv.AADConfig{}
if err = intazkv.LoadAADConfigFromBytes(value, &conf); err != nil {
@ -253,11 +265,16 @@ func (d *Decryptor) ImportKeys(ctx context.Context) error {
if err != nil {
return fmt.Errorf("failed to import '%s' data from %s decryption Secret '%s': %w", name, provider, secretName, err)
}
d.azureToken = azkv.NewTokenCredential(azureToken)
d.azureTokenCredential = azureToken
}
case filepath.Ext(DecryptionGCPCredsFile):
if name == DecryptionGCPCredsFile {
d.gcpCredsJSON = bytes.Trim(value, "\n")
creds, err := google.CredentialsFromJSON(ctx,
bytes.Trim(value, "\n"), gcpkmsapi.DefaultAuthScopes()...)
if err != nil {
return fmt.Errorf("failed to import '%s' data from %s decryption Secret '%s': %w", name, provider, secretName, err)
}
d.gcpTokenSource = creds.TokenSource
}
}
}
@ -265,6 +282,63 @@ func (d *Decryptor) ImportKeys(ctx context.Context) error {
return nil
}
// SetAuthOptions sets the authentication options for secret-less authentication
// with cloud providers.
func (d *Decryptor) SetAuthOptions(ctx context.Context) {
if d.kustomization.Spec.Decryption == nil {
return
}
switch d.kustomization.Spec.Decryption.Provider {
case DecryptionProviderSOPS:
var opts []auth.Option
if d.kustomization.Spec.Decryption.ServiceAccountName != "" {
serviceAccount := types.NamespacedName{
Name: d.kustomization.Spec.Decryption.ServiceAccountName,
Namespace: d.kustomization.GetNamespace(),
}
opts = append(opts, auth.WithServiceAccount(serviceAccount, d.client))
}
involvedObject := cache.InvolvedObject{
Kind: kustomizev1.KustomizationKind,
Name: d.kustomization.GetName(),
Namespace: d.kustomization.GetNamespace(),
}
if d.awsCredentialsProvider == nil {
awsOpts := opts
if d.tokenCache != nil {
involvedObject.Operation = intcache.OperationDecryptWithAWS
awsOpts = append(awsOpts, auth.WithCache(*d.tokenCache, involvedObject))
}
d.awsCredentialsProvider = func(region string) awssdk.CredentialsProvider {
awsOpts := append(awsOpts, auth.WithSTSRegion(region))
return aws.NewCredentialsProvider(ctx, awsOpts...)
}
}
if d.azureTokenCredential == nil {
azureOpts := opts
if d.tokenCache != nil {
involvedObject.Operation = intcache.OperationDecryptWithAzure
azureOpts = append(azureOpts, auth.WithCache(*d.tokenCache, involvedObject))
}
d.azureTokenCredential = azure.NewTokenCredential(ctx, azureOpts...)
}
if d.gcpTokenSource == nil {
gcpOpts := opts
if d.tokenCache != nil {
involvedObject.Operation = intcache.OperationDecryptWithGCP
gcpOpts = append(gcpOpts, auth.WithCache(*d.tokenCache, involvedObject))
}
d.gcpTokenSource = gcp.NewTokenSource(ctx, gcpOpts...)
}
}
}
// SopsDecryptWithFormat attempts to load a SOPS encrypted file using the store
// for the input format, gathers the data key for it from the key service,
// and then decrypts the file data with the retrieved data key.
@ -292,7 +366,7 @@ func (d *Decryptor) SopsDecryptWithFormat(data []byte, inputFormat, outputFormat
}
cipher := aes.NewCipher()
mac, err := tree.Decrypt(metadataKey, cipher)
mac, err := safeDecrypt(tree.Decrypt(metadataKey, cipher))
if err != nil {
return nil, sopsUserErr("error decrypting sops tree", err)
}
@ -302,11 +376,11 @@ func (d *Decryptor) SopsDecryptWithFormat(data []byte, inputFormat, outputFormat
// the one that was stored in the document. If they match,
// integrity was preserved
// Ref: github.com/getsops/sops/v3/decrypt/decrypt.go
originalMac, err := cipher.Decrypt(
originalMac, err := safeDecrypt(cipher.Decrypt(
tree.Metadata.MessageAuthenticationCode,
metadataKey,
tree.Metadata.LastModified.Format(time.RFC3339),
)
))
if err != nil {
return nil, sopsUserErr("failed to verify sops data integrity", err)
}
@ -582,12 +656,10 @@ func (d *Decryptor) loadKeyServiceServer() {
intkeyservice.WithGnuPGHome(d.gnuPGHome),
intkeyservice.WithVaultToken(d.vaultToken),
intkeyservice.WithAgeIdentities(d.ageIdentities),
intkeyservice.WithGCPCredsJSON(d.gcpCredsJSON),
intkeyservice.WithAWSCredentialsProvider{CredentialsProvider: d.awsCredentialsProvider},
intkeyservice.WithAzureTokenCredential{TokenCredential: d.azureTokenCredential},
intkeyservice.WithGCPTokenSource{TokenSource: d.gcpTokenSource},
}
if d.azureToken != nil {
serverOpts = append(serverOpts, intkeyservice.WithAzureToken{Token: d.azureToken})
}
serverOpts = append(serverOpts, intkeyservice.WithAWSKeys{CredsProvider: d.awsCredsProvider})
server := intkeyservice.NewServer(serverOpts...)
d.keyServices = append(make([]keyservice.KeyServiceClient, 0), keyservice.NewCustomLocalClient(server))
}
@ -782,7 +854,7 @@ func stripRoot(root, path string) string {
func sopsUserErr(msg string, err error) error {
if userErr, ok := err.(sops.UserError); ok {
err = fmt.Errorf(userErr.UserError())
err = errors.New(userErr.UserError())
}
return fmt.Errorf("%s: %w", msg, err)
}
@ -811,3 +883,33 @@ func detectFormatFromMarkerBytes(b []byte) formats.Format {
}
return unsupportedFormat
}
// safeDecrypt redacts secret values in sops error messages.
func safeDecrypt[T any](mac T, err error) (T, error) {
const (
prefix = "Input string "
suffix = " does not match sops' data format"
)
if err == nil {
return mac, nil
}
var buf strings.Builder
e := err.Error()
prefIdx := strings.Index(e, prefix)
suffIdx := strings.Index(e, suffix)
var zero T
if prefIdx == -1 || suffIdx == -1 {
return zero, err
}
buf.WriteString(e[:prefIdx])
buf.WriteString(prefix)
buf.WriteString("<redacted>")
buf.WriteString(suffix)
return zero, errors.New(buf.String())
}

View File

@ -20,6 +20,7 @@ import (
"bytes"
"context"
"encoding/base64"
"errors"
"fmt"
"io/fs"
"os"
@ -209,7 +210,7 @@ aws_session_token: test-token`),
},
},
inspectFunc: func(g *GomegaWithT, decryptor *Decryptor) {
g.Expect(decryptor.awsCredsProvider).ToNot(BeNil())
g.Expect(decryptor.awsCredentialsProvider).ToNot(BeNil())
},
},
{
@ -232,7 +233,7 @@ aws_session_token: test-token`),
},
},
inspectFunc: func(g *GomegaWithT, decryptor *Decryptor) {
g.Expect(decryptor.gcpCredsJSON).ToNot(BeNil())
g.Expect(decryptor.gcpTokenSource).ToNot(BeNil())
},
},
{
@ -255,7 +256,7 @@ clientSecret: some-client-secret`),
},
},
inspectFunc: func(g *GomegaWithT, decryptor *Decryptor) {
g.Expect(decryptor.azureToken).ToNot(BeNil())
g.Expect(decryptor.azureTokenCredential).ToNot(BeNil())
},
},
{
@ -277,7 +278,7 @@ clientSecret: some-client-secret`),
},
wantErr: true,
inspectFunc: func(g *GomegaWithT, decryptor *Decryptor) {
g.Expect(decryptor.azureToken).To(BeNil())
g.Expect(decryptor.azureTokenCredential).To(BeNil())
},
},
{
@ -299,7 +300,7 @@ clientSecret: some-client-secret`),
},
wantErr: true,
inspectFunc: func(g *GomegaWithT, decryptor *Decryptor) {
g.Expect(decryptor.azureToken).To(BeNil())
g.Expect(decryptor.azureTokenCredential).To(BeNil())
},
},
{
@ -375,7 +376,7 @@ clientSecret: some-client-secret`),
},
}
d, cleanup, err := NewTempDecryptor("", cb.Build(), &kustomization)
d, cleanup, err := NewTempDecryptor("", cb.Build(), &kustomization, nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -392,6 +393,60 @@ clientSecret: some-client-secret`),
}
}
func TestDecryptor_SetAuthOptions(t *testing.T) {
t.Run("nil decryption settings", func(t *testing.T) {
g := NewWithT(t)
d := &Decryptor{
kustomization: &kustomizev1.Kustomization{},
}
d.SetAuthOptions(context.Background())
g.Expect(d.awsCredentialsProvider).To(BeNil())
g.Expect(d.azureTokenCredential).To(BeNil())
g.Expect(d.gcpTokenSource).To(BeNil())
})
t.Run("non-sops provider", func(t *testing.T) {
g := NewWithT(t)
d := &Decryptor{
kustomization: &kustomizev1.Kustomization{
Spec: kustomizev1.KustomizationSpec{
Decryption: &kustomizev1.Decryption{},
},
},
}
d.SetAuthOptions(context.Background())
g.Expect(d.awsCredentialsProvider).To(BeNil())
g.Expect(d.azureTokenCredential).To(BeNil())
g.Expect(d.gcpTokenSource).To(BeNil())
})
t.Run("sops provider", func(t *testing.T) {
g := NewWithT(t)
d := &Decryptor{
kustomization: &kustomizev1.Kustomization{
Spec: kustomizev1.KustomizationSpec{
Decryption: &kustomizev1.Decryption{
Provider: DecryptionProviderSOPS,
},
},
},
}
d.SetAuthOptions(context.Background())
g.Expect(d.awsCredentialsProvider).NotTo(BeNil())
g.Expect(d.azureTokenCredential).NotTo(BeNil())
g.Expect(d.gcpTokenSource).NotTo(BeNil())
})
}
func TestDecryptor_SopsDecryptWithFormat(t *testing.T) {
t.Run("decrypt INI to INI", func(t *testing.T) {
g := NewWithT(t)
@ -550,7 +605,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
Provider: DecryptionProviderSOPS,
}
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus)
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -591,7 +646,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
Provider: DecryptionProviderSOPS,
}
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus)
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -626,7 +681,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
Provider: DecryptionProviderSOPS,
}
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus)
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -661,7 +716,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
Provider: DecryptionProviderSOPS,
}
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus)
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -703,13 +758,14 @@ func TestDecryptor_DecryptResource(t *testing.T) {
got, err := d.DecryptResource(secret)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(got).ToNot(BeNil())
g.Expect(got.GetDataMap()).To(HaveKeyWithValue(corev1.DockerConfigJsonKey, base64.StdEncoding.EncodeToString(plainData)))
plainDataWithTrailingNewline := append(plainData, '\n') // https://github.com/getsops/sops/issues/1825
g.Expect(got.GetDataMap()).To(HaveKeyWithValue(corev1.DockerConfigJsonKey, base64.StdEncoding.EncodeToString(plainDataWithTrailingNewline)))
})
t.Run("nil resource", func(t *testing.T) {
g := NewWithT(t)
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kustomization.DeepCopy())
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kustomization.DeepCopy(), nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -721,7 +777,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
t.Run("no decryption spec", func(t *testing.T) {
g := NewWithT(t)
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kustomization.DeepCopy())
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kustomization.DeepCopy(), nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -737,7 +793,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
kus.Spec.Decryption = &kustomizev1.Decryption{
Provider: "not-supported",
}
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus)
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
g.Expect(err).ToNot(HaveOccurred())
t.Cleanup(cleanup)
@ -1598,3 +1654,54 @@ func TestDecryptor_detectFormatFromMarkerBytes(t *testing.T) {
})
}
}
func TestSafeDecrypt(t *testing.T) {
for _, tt := range []struct {
name string
mac string
err string
expectedMac string
expectedErr string
}{
{
name: "no error",
mac: "some mac",
expectedMac: "some mac",
},
{
name: "only prefix",
err: "Input string was not in a correct format",
expectedErr: "Input string was not in a correct format",
},
{
name: "only suffix",
err: "The value does not match sops' data format",
expectedErr: "The value does not match sops' data format",
},
{
name: "redacted value",
err: "Input string 1234567897 does not match sops' data format",
expectedErr: "Input string <redacted> does not match sops' data format",
},
} {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
var err error
if tt.err != "" {
err = errors.New(tt.err)
}
mac, err := safeDecrypt(tt.mac, err)
g.Expect(mac).To(Equal(tt.expectedMac))
if tt.expectedErr == "" {
g.Expect(err).To(Not(HaveOccurred()))
} else {
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(Equal(tt.expectedErr))
}
})
}
}

View File

@ -18,7 +18,10 @@ limitations under the License.
// and their default states.
package features
import feathelper "github.com/fluxcd/pkg/runtime/features"
import (
"github.com/fluxcd/pkg/auth"
feathelper "github.com/fluxcd/pkg/runtime/features"
)
const (
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
@ -68,6 +71,10 @@ var features = map[string]bool{
GroupChangeLog: false,
}
func init() {
auth.SetFeatureGates(features)
}
// FeatureGates contains a list of all supported feature gates and
// their default values.
func FeatureGates() map[string]bool {

View File

@ -0,0 +1,27 @@
/*
Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package awskms
import (
"strings"
)
// GetRegionFromKMSARN extracts the region from a KMS ARN.
func GetRegionFromKMSARN(arn string) string {
arn = strings.TrimPrefix(arn, "arn:aws:kms:")
return strings.SplitN(arn, ":", 2)[0]
}

View File

@ -0,0 +1,34 @@
/*
Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package awskms_test
import (
"testing"
. "github.com/onsi/gomega"
"github.com/fluxcd/kustomize-controller/internal/sops/awskms"
)
func TestGetRegionFromKMSARN(t *testing.T) {
g := NewWithT(t)
arn := "arn:aws:kms:us-east-1:211125720409:key/mrk-3179bb7e88bc42ffb1a27d5038ceea25"
region := awskms.GetRegionFromKMSARN(arn)
g.Expect(region).To(Equal("us-east-1"))
}

View File

@ -1,103 +0,0 @@
/*
Copyright 2023 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package azkv
import (
"errors"
"fmt"
"os"
"strings"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
)
// DefaultTokenCredential is a modification of azidentity.NewDefaultAzureCredential,
// specifically adapted to not shell out to the Azure CLI.
//
// It attempts to return an azcore.TokenCredential based on the following order:
//
// - azidentity.NewEnvironmentCredential if environment variables AZURE_CLIENT_ID,
// AZURE_CLIENT_ID is set with either one of the following: (AZURE_CLIENT_SECRET)
// or (AZURE_CLIENT_CERTIFICATE_PATH and AZURE_CLIENT_CERTIFICATE_PATH) or
// (AZURE_USERNAME, AZURE_PASSWORD)
// - azidentity.WorkloadIdentityCredential if environment variable configuration
// (AZURE_AUTHORITY_HOST, AZURE_CLIENT_ID, AZURE_FEDERATED_TOKEN_FILE, AZURE_TENANT_ID)
// is set by the Azure workload identity webhook.
// - azidentity.ManagedIdentityCredential if only AZURE_CLIENT_ID env variable is set.
func DefaultTokenCredential() (azcore.TokenCredential, error) {
var (
azureClientID = "AZURE_CLIENT_ID"
azureFederatedTokenFile = "AZURE_FEDERATED_TOKEN_FILE"
azureAuthorityHost = "AZURE_AUTHORITY_HOST"
azureTenantID = "AZURE_TENANT_ID"
)
var errorMessages []string
options := &azidentity.DefaultAzureCredentialOptions{}
envCred, err := azidentity.NewEnvironmentCredential(&azidentity.EnvironmentCredentialOptions{
ClientOptions: options.ClientOptions, DisableInstanceDiscovery: options.DisableInstanceDiscovery},
)
if err == nil {
return envCred, nil
} else {
errorMessages = append(errorMessages, "EnvironmentCredential: "+err.Error())
}
// workload identity requires values for AZURE_AUTHORITY_HOST, AZURE_CLIENT_ID, AZURE_FEDERATED_TOKEN_FILE, AZURE_TENANT_ID
haveWorkloadConfig := false
clientID, haveClientID := os.LookupEnv(azureClientID)
if haveClientID {
if file, ok := os.LookupEnv(azureFederatedTokenFile); ok {
if _, ok := os.LookupEnv(azureAuthorityHost); ok {
if tenantID, ok := os.LookupEnv(azureTenantID); ok {
haveWorkloadConfig = true
workloadCred, err := azidentity.NewWorkloadIdentityCredential(&azidentity.WorkloadIdentityCredentialOptions{
ClientID: clientID,
TenantID: tenantID,
TokenFilePath: file,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
})
if err == nil {
return workloadCred, nil
} else {
errorMessages = append(errorMessages, "Workload Identity"+": "+err.Error())
}
}
}
}
}
if !haveWorkloadConfig {
err := errors.New("missing environment variables for workload identity. Check webhook and pod configuration")
errorMessages = append(errorMessages, fmt.Sprintf("Workload Identity: %s", err))
}
o := &azidentity.ManagedIdentityCredentialOptions{ClientOptions: options.ClientOptions}
if haveClientID {
o.ID = azidentity.ClientID(clientID)
}
miCred, err := azidentity.NewManagedIdentityCredential(o)
if err == nil {
return miCred, nil
} else {
errorMessages = append(errorMessages, "ManagedIdentity"+": "+err.Error())
}
return nil, errors.New(strings.Join(errorMessages, "\n"))
}

View File

@ -18,6 +18,8 @@ package keyservice
import (
extage "filippo.io/age"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
awssdk "github.com/aws/aws-sdk-go-v2/aws"
"github.com/getsops/sops/v3/age"
"github.com/getsops/sops/v3/azkv"
"github.com/getsops/sops/v3/gcpkms"
@ -25,6 +27,9 @@ import (
"github.com/getsops/sops/v3/keyservice"
awskms "github.com/getsops/sops/v3/kms"
"github.com/getsops/sops/v3/pgp"
"golang.org/x/oauth2"
intawskms "github.com/fluxcd/kustomize-controller/internal/sops/awskms"
)
// ServerOption is some configuration that modifies the Server.
@ -57,33 +62,38 @@ func (o WithAgeIdentities) ApplyToServer(s *Server) {
s.ageIdentities = age.ParsedIdentities(o)
}
// WithAWSKeys configures the AWS credentials on the Server
type WithAWSKeys struct {
CredsProvider *awskms.CredentialsProvider
// WithAWSCredentialsProvider configures the AWS credentials on the Server
type WithAWSCredentialsProvider struct {
CredentialsProvider func(region string) awssdk.CredentialsProvider
}
// ApplyToServer applies this configuration to the given Server.
func (o WithAWSKeys) ApplyToServer(s *Server) {
s.awsCredsProvider = o.CredsProvider
func (o WithAWSCredentialsProvider) ApplyToServer(s *Server) {
s.awsCredentialsProvider = func(arn string) *awskms.CredentialsProvider {
region := intawskms.GetRegionFromKMSARN(arn)
cp := o.CredentialsProvider(region)
return awskms.NewCredentialsProvider(cp)
}
}
// WithGCPCredsJSON configures the GCP service account credentials JSON on the
// Server.
type WithGCPCredsJSON []byte
// ApplyToServer applies this configuration to the given Server.
func (o WithGCPCredsJSON) ApplyToServer(s *Server) {
s.gcpCredsJSON = gcpkms.CredentialJSON(o)
}
// WithAzureToken configures the Azure credential token on the Server.
type WithAzureToken struct {
Token *azkv.TokenCredential
// WithGCPTokenSource configures the GCP token source on the Server.
type WithGCPTokenSource struct {
TokenSource oauth2.TokenSource
}
// ApplyToServer applies this configuration to the given Server.
func (o WithAzureToken) ApplyToServer(s *Server) {
s.azureToken = o.Token
func (o WithGCPTokenSource) ApplyToServer(s *Server) {
s.gcpTokenSource = gcpkms.NewTokenSource(o.TokenSource)
}
// WithAzureTokenCredential configures the Azure credential token on the Server.
type WithAzureTokenCredential struct {
TokenCredential azcore.TokenCredential
}
// ApplyToServer applies this configuration to the given Server.
func (o WithAzureTokenCredential) ApplyToServer(s *Server) {
s.azureTokenCredential = azkv.NewTokenCredential(o.TokenCredential)
}
// WithDefaultServer configures the fallback default server on the Server.

View File

@ -28,8 +28,6 @@ import (
"github.com/getsops/sops/v3/logging"
"github.com/getsops/sops/v3/pgp"
"golang.org/x/net/context"
intazkv "github.com/fluxcd/kustomize-controller/internal/sops/azkv"
)
// Server is a key service server that uses SOPS MasterKeys to fulfill
@ -54,20 +52,19 @@ type Server struct {
// When empty, the request will be handled by defaultServer.
vaultToken hcvault.Token
// azureToken is the credential token used for Encrypt and Decrypt
// azureTokenCredential is the credential token used for Encrypt and Decrypt
// operations of Azure Key Vault requests.
// When nil, the request will be handled by defaultServer.
azureToken *azkv.TokenCredential
azureTokenCredential *azkv.TokenCredential
// awsCredsProvider is the Credentials object used for Encrypt and Decrypt
// awsCredentialsProvider is the Credentials object used for Encrypt and Decrypt
// operations of AWS KMS requests.
// When nil, the request will be handled by defaultServer.
awsCredsProvider *awskms.CredentialsProvider
awsCredentialsProvider func(arn string) *awskms.CredentialsProvider
// gcpCredsJSON is the JSON credentials used for Decrypt and Encrypt
// operations of GCP KMS requests. When nil, a default client with
// environmental runtime settings will be used.
gcpCredsJSON gcpkms.CredentialJSON
// gcpTokenSource is the token source used for Encrypt and Decrypt
// operations of GCP KMS requests.
gcpTokenSource gcpkms.TokenSource
// defaultServer is the fallback server, used to handle any request that
// is not eligible to be handled by this Server.
@ -296,9 +293,7 @@ func (ks *Server) decryptWithHCVault(key *keyservice.VaultKey, ciphertext []byte
func (ks *Server) encryptWithAWSKMS(key *keyservice.KmsKey, plaintext []byte) ([]byte, error) {
awsKey := kmsKeyToMasterKey(key)
if ks.awsCredsProvider != nil {
ks.awsCredsProvider.ApplyToMasterKey(&awsKey)
}
ks.awsCredentialsProvider(key.Arn).ApplyToMasterKey(&awsKey)
if err := awsKey.Encrypt(plaintext); err != nil {
return nil, err
}
@ -308,9 +303,7 @@ func (ks *Server) encryptWithAWSKMS(key *keyservice.KmsKey, plaintext []byte) ([
func (ks *Server) decryptWithAWSKMS(key *keyservice.KmsKey, cipherText []byte) ([]byte, error) {
awsKey := kmsKeyToMasterKey(key)
awsKey.EncryptedKey = string(cipherText)
if ks.awsCredsProvider != nil {
ks.awsCredsProvider.ApplyToMasterKey(&awsKey)
}
ks.awsCredentialsProvider(key.Arn).ApplyToMasterKey(&awsKey)
return awsKey.Decrypt()
}
@ -320,17 +313,7 @@ func (ks *Server) encryptWithAzureKeyVault(key *keyservice.AzureKeyVaultKey, pla
Name: key.Name,
Version: key.Version,
}
if ks.azureToken == nil {
// Ensure we use the default token credential if none is provided
// _without_ shelling out to `az`.
defaultToken, err := intazkv.DefaultTokenCredential()
if err != nil {
return nil, fmt.Errorf("failed to get Azure token credential to encrypt data: %w", err)
}
azkv.NewTokenCredential(defaultToken).ApplyToMasterKey(&azureKey)
} else {
ks.azureToken.ApplyToMasterKey(&azureKey)
}
ks.azureTokenCredential.ApplyToMasterKey(&azureKey)
if err := azureKey.Encrypt(plaintext); err != nil {
return nil, err
}
@ -343,17 +326,7 @@ func (ks *Server) decryptWithAzureKeyVault(key *keyservice.AzureKeyVaultKey, cip
Name: key.Name,
Version: key.Version,
}
if ks.azureToken == nil {
// Ensure we use the default token credential if none is provided
// _without_ shelling out to `az`.
defaultToken, err := intazkv.DefaultTokenCredential()
if err != nil {
return nil, fmt.Errorf("failed to get Azure token credential to decrypt data: %w", err)
}
azkv.NewTokenCredential(defaultToken).ApplyToMasterKey(&azureKey)
} else {
ks.azureToken.ApplyToMasterKey(&azureKey)
}
ks.azureTokenCredential.ApplyToMasterKey(&azureKey)
azureKey.EncryptedKey = string(ciphertext)
plaintext, err := azureKey.Decrypt()
return plaintext, err
@ -363,7 +336,7 @@ func (ks *Server) encryptWithGCPKMS(key *keyservice.GcpKmsKey, plaintext []byte)
gcpKey := gcpkms.MasterKey{
ResourceID: key.ResourceId,
}
ks.gcpCredsJSON.ApplyToMasterKey(&gcpKey)
ks.gcpTokenSource.ApplyToMasterKey(&gcpKey)
if err := gcpKey.Encrypt(plaintext); err != nil {
return nil, err
}
@ -374,7 +347,7 @@ func (ks *Server) decryptWithGCPKMS(key *keyservice.GcpKmsKey, ciphertext []byte
gcpKey := gcpkms.MasterKey{
ResourceID: key.ResourceId,
}
ks.gcpCredsJSON.ApplyToMasterKey(&gcpKey)
ks.gcpTokenSource.ApplyToMasterKey(&gcpKey)
gcpKey.EncryptedKey = string(ciphertext)
plaintext, err := gcpKey.Decrypt()
return plaintext, err

View File

@ -21,7 +21,9 @@ import (
"os"
"testing"
gcpkmsapi "cloud.google.com/go/kms/apiv1"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/getsops/sops/v3/age"
"github.com/getsops/sops/v3/azkv"
@ -32,6 +34,7 @@ import (
"github.com/getsops/sops/v3/pgp"
. "github.com/onsi/gomega"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
)
func TestServer_EncryptDecrypt_PGP(t *testing.T) {
@ -151,8 +154,8 @@ func TestServer_EncryptDecrypt_HCVault_Fallback(t *testing.T) {
func TestServer_EncryptDecrypt_awskms(t *testing.T) {
g := NewWithT(t)
s := NewServer(WithAWSKeys{
CredsProvider: awskms.NewCredentialsProvider(credentials.StaticCredentialsProvider{}),
s := NewServer(WithAWSCredentialsProvider{
CredentialsProvider: func(region string) aws.CredentialsProvider { return credentials.StaticCredentialsProvider{} },
})
key := KeyFromMasterKey(awskms.NewMasterKeyFromArn("arn:aws:kms:us-west-2:107501996527:key/612d5f0p-p1l3-45e6-aca6-a5b005693a48", nil, ""))
@ -174,7 +177,7 @@ func TestServer_EncryptDecrypt_azkv(t *testing.T) {
identity, err := azidentity.NewDefaultAzureCredential(nil)
g.Expect(err).ToNot(HaveOccurred())
s := NewServer(WithAzureToken{Token: azkv.NewTokenCredential(identity)})
s := NewServer(WithAzureTokenCredential{TokenCredential: identity})
key := KeyFromMasterKey(azkv.NewMasterKey("", "", ""))
_, err = s.Encrypt(context.TODO(), &keyservice.EncryptRequest{
@ -194,24 +197,24 @@ func TestServer_EncryptDecrypt_azkv(t *testing.T) {
func TestServer_EncryptDecrypt_gcpkms(t *testing.T) {
g := NewWithT(t)
creds := `{ "client_id": "<client-id>.apps.googleusercontent.com",
"client_secret": "<secret>",
"type": "authorized_user"}`
s := NewServer(WithGCPCredsJSON([]byte(creds)))
creds, err := google.CredentialsFromJSON(context.Background(),
[]byte(`{"type":"service_account"}`), gcpkmsapi.DefaultAuthScopes()...)
g.Expect(err).ToNot(HaveOccurred())
s := NewServer(WithGCPTokenSource{TokenSource: creds.TokenSource})
resourceID := "projects/test-flux/locations/global/keyRings/test-flux/cryptoKeys/sops"
key := KeyFromMasterKey(gcpkms.NewMasterKeyFromResourceID(resourceID))
_, err := s.Encrypt(context.TODO(), &keyservice.EncryptRequest{
_, err = s.Encrypt(context.TODO(), &keyservice.EncryptRequest{
Key: &key,
})
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(ContainSubstring("cannot create GCP KMS service"))
g.Expect(err.Error()).To(ContainSubstring("failed to encrypt sops data key with GCP KMS key"))
_, err = s.Decrypt(context.TODO(), &keyservice.DecryptRequest{
Key: &key,
})
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(ContainSubstring("cannot create GCP KMS service"))
g.Expect(err.Error()).To(ContainSubstring("failed to decrypt sops data key with GCP KMS key"))
}

View File

@ -1,118 +0,0 @@
/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package statusreaders
import (
"context"
"fmt"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling/engine"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling/event"
kstatusreaders "github.com/fluxcd/cli-utils/pkg/kstatus/polling/statusreaders"
"github.com/fluxcd/cli-utils/pkg/kstatus/status"
"github.com/fluxcd/cli-utils/pkg/object"
)
type customJobStatusReader struct {
genericStatusReader engine.StatusReader
}
func NewCustomJobStatusReader(mapper meta.RESTMapper) engine.StatusReader {
genericStatusReader := kstatusreaders.NewGenericStatusReader(mapper, jobConditions)
return &customJobStatusReader{
genericStatusReader: genericStatusReader,
}
}
func (j *customJobStatusReader) Supports(gk schema.GroupKind) bool {
return gk == batchv1.SchemeGroupVersion.WithKind("Job").GroupKind()
}
func (j *customJobStatusReader) ReadStatus(ctx context.Context, reader engine.ClusterReader, resource object.ObjMetadata) (*event.ResourceStatus, error) {
return j.genericStatusReader.ReadStatus(ctx, reader, resource)
}
func (j *customJobStatusReader) ReadStatusForObject(ctx context.Context, reader engine.ClusterReader, resource *unstructured.Unstructured) (*event.ResourceStatus, error) {
return j.genericStatusReader.ReadStatusForObject(ctx, reader, resource)
}
// Ref: https://github.com/kubernetes-sigs/cli-utils/blob/v0.29.4/pkg/kstatus/status/core.go
// Modified to return Current status only when the Job has completed as opposed to when it's in progress.
func jobConditions(u *unstructured.Unstructured) (*status.Result, error) {
obj := u.UnstructuredContent()
parallelism := status.GetIntField(obj, ".spec.parallelism", 1)
completions := status.GetIntField(obj, ".spec.completions", parallelism)
succeeded := status.GetIntField(obj, ".status.succeeded", 0)
failed := status.GetIntField(obj, ".status.failed", 0)
// Conditions
// https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/job/utils.go#L24
objc, err := status.GetObjectWithConditions(obj)
if err != nil {
return nil, err
}
for _, c := range objc.Status.Conditions {
switch c.Type {
case "Complete":
if c.Status == corev1.ConditionTrue {
message := fmt.Sprintf("Job Completed. succeeded: %d/%d", succeeded, completions)
return &status.Result{
Status: status.CurrentStatus,
Message: message,
Conditions: []status.Condition{},
}, nil
}
case "Failed":
message := fmt.Sprintf("Job Failed. failed: %d/%d", failed, completions)
if c.Status == corev1.ConditionTrue {
return &status.Result{
Status: status.FailedStatus,
Message: message,
Conditions: []status.Condition{
{
Type: status.ConditionStalled,
Status: corev1.ConditionTrue,
Reason: "JobFailed",
Message: message,
},
},
}, nil
}
}
}
message := "Job in progress"
return &status.Result{
Status: status.InProgressStatus,
Message: message,
Conditions: []status.Condition{
{
Type: status.ConditionReconciling,
Status: corev1.ConditionTrue,
Reason: "JobInProgress",
Message: message,
},
},
}, nil
}

View File

@ -1,65 +0,0 @@
/*
Copyright 2022 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package statusreaders
import (
"testing"
. "github.com/onsi/gomega"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/cli-utils/pkg/kstatus/status"
"github.com/fluxcd/pkg/runtime/patch"
)
func Test_jobConditions(t *testing.T) {
job := &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "job",
},
Spec: batchv1.JobSpec{},
Status: batchv1.JobStatus{},
}
t.Run("job without Complete condition returns InProgress status", func(t *testing.T) {
g := NewWithT(t)
us, err := patch.ToUnstructured(job)
g.Expect(err).ToNot(HaveOccurred())
result, err := jobConditions(us)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(result.Status).To(Equal(status.InProgressStatus))
})
t.Run("job with Complete condition as True returns Current status", func(t *testing.T) {
g := NewWithT(t)
job.Status = batchv1.JobStatus{
Conditions: []batchv1.JobCondition{
{
Type: batchv1.JobComplete,
Status: corev1.ConditionTrue,
},
},
}
us, err := patch.ToUnstructured(job)
g.Expect(err).ToNot(HaveOccurred())
result, err := jobConditions(us)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(result.Status).To(Equal(status.CurrentStatus))
})
}

50
main.go
View File

@ -32,11 +32,13 @@ import (
ctrlcache "sigs.k8s.io/controller-runtime/pkg/cache"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
ctrlcfg "sigs.k8s.io/controller-runtime/pkg/config"
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling/clusterreader"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling/engine"
"github.com/fluxcd/pkg/auth"
pkgcache "github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/runtime/acl"
runtimeClient "github.com/fluxcd/pkg/runtime/client"
runtimeCtrl "github.com/fluxcd/pkg/runtime/controller"
@ -49,12 +51,10 @@ import (
"github.com/fluxcd/pkg/runtime/pprof"
"github.com/fluxcd/pkg/runtime/probes"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/kustomize-controller/internal/controller"
"github.com/fluxcd/kustomize-controller/internal/features"
"github.com/fluxcd/kustomize-controller/internal/statusreaders"
// +kubebuilder:scaffold:imports
)
@ -69,12 +69,15 @@ func init() {
_ = clientgoscheme.AddToScheme(scheme)
_ = sourcev1.AddToScheme(scheme)
_ = sourcev1b2.AddToScheme(scheme)
_ = kustomizev1.AddToScheme(scheme)
// +kubebuilder:scaffold:scheme
}
func main() {
const (
tokenCacheDefaultMaxSize = 100
)
var (
metricsAddr string
eventsAddr string
@ -95,6 +98,7 @@ func main() {
defaultServiceAccount string
featureGates feathelper.FeatureGates
disallowedFieldManagers []string
tokenCacheOptions pkgcache.TokenFlags
)
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
@ -118,6 +122,7 @@ func main() {
featureGates.BindFlags(flag.CommandLine)
watchOptions.BindFlags(flag.CommandLine)
intervalJitterOptions.BindFlags(flag.CommandLine)
tokenCacheOptions.BindFlags(flag.CommandLine, tokenCacheDefaultMaxSize)
flag.Parse()
@ -130,6 +135,14 @@ func main() {
os.Exit(1)
}
switch enabled, err := features.Enabled(auth.FeatureGateObjectLevelWorkloadIdentity); {
case err != nil:
setupLog.Error(err, "unable to check feature gate "+auth.FeatureGateObjectLevelWorkloadIdentity)
os.Exit(1)
case enabled:
auth.EnableObjectLevelWorkloadIdentity()
}
if err := intervalJitterOptions.SetGlobalJitter(nil); err != nil {
setupLog.Error(err, "unable to set global jitter")
os.Exit(1)
@ -214,13 +227,15 @@ func main() {
metricsH := runtimeCtrl.NewMetrics(mgr, metrics.MustMakeRecorder(), kustomizev1.KustomizationFinalizer)
jobStatusReader := statusreaders.NewCustomJobStatusReader(mgr.GetRESTMapper())
pollingOpts := polling.Options{
CustomStatusReaders: []engine.StatusReader{jobStatusReader},
restMapper, err := runtimeClient.NewDynamicRESTMapper(mgr.GetConfig())
if err != nil {
setupLog.Error(err, "unable to create REST mapper")
os.Exit(1)
}
var clusterReader engine.ClusterReaderFactory
if ok, _ := features.Enabled(features.DisableStatusPollerCache); ok {
pollingOpts.ClusterReaderFactory = engine.ClusterReaderFactoryFunc(clusterreader.NewDirectClusterReader)
clusterReader = engine.ClusterReaderFactoryFunc(clusterreader.NewDirectClusterReader)
}
failFast := true
@ -240,11 +255,24 @@ func main() {
os.Exit(1)
}
var tokenCache *pkgcache.TokenCache
if tokenCacheOptions.MaxSize > 0 {
var err error
tokenCache, err = pkgcache.NewTokenCache(tokenCacheOptions.MaxSize,
pkgcache.WithMaxDuration(tokenCacheOptions.MaxDuration),
pkgcache.WithMetricsRegisterer(ctrlmetrics.Registry),
pkgcache.WithMetricsPrefix("gotk_token_"))
if err != nil {
setupLog.Error(err, "unable to create token cache")
os.Exit(1)
}
}
if err = (&controller.KustomizationReconciler{
ControllerName: controllerName,
DefaultServiceAccount: defaultServiceAccount,
Client: mgr.GetClient(),
Mapper: mgr.GetRESTMapper(),
Mapper: restMapper,
APIReader: mgr.GetAPIReader(),
Metrics: metricsH,
EventRecorder: eventRecorder,
@ -253,11 +281,11 @@ func main() {
FailFast: failFast,
ConcurrentSSA: concurrentSSA,
KubeConfigOpts: kubeConfigOpts,
PollingOpts: pollingOpts,
StatusPoller: polling.NewStatusPoller(mgr.GetClient(), mgr.GetRESTMapper(), pollingOpts),
ClusterReader: clusterReader,
DisallowedFieldManagers: disallowedFieldManagers,
StrictSubstitutions: strictSubstitutions,
GroupChangeLog: groupChangeLog,
TokenCache: tokenCache,
}).SetupWithManager(ctx, mgr, controller.KustomizationReconcilerOptions{
DependencyRequeueInterval: requeueDependency,
HTTPRetry: httpRetry,

View File

@ -1,9 +1,9 @@
FROM gcr.io/oss-fuzz-base/base-builder-go
RUN wget https://go.dev/dl/go1.23.0.linux-amd64.tar.gz \
RUN wget https://go.dev/dl/go1.24.0.linux-amd64.tar.gz \
&& mkdir temp-go \
&& rm -rf /root/.go/* \
&& tar -C temp-go/ -xzf go1.23.0.linux-amd64.tar.gz \
&& tar -C temp-go/ -xzf go1.24.0.linux-amd64.tar.gz \
&& mv temp-go/go/* /root/.go/
ENV SRC=$GOPATH/src/github.com/fluxcd/kustomize-controller