Compare commits

..

40 Commits

Author SHA1 Message Date
Stefan Prodan 6243cf04cd
Merge pull request #957 from fluxcd/k8s-1.34
Update to Kubernetes v1.34.0 and Go 1.25.0
2025-08-31 17:57:48 +03:00
Stefan Prodan b1c0cad5d8
Build with Go 1.25
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-08-31 16:11:32 +03:00
Stefan Prodan 47cc2cb901
Regenerate CRDs with controller-gen v0.19
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-08-31 15:41:16 +03:00
Stefan Prodan 8dad1fd2da
Update dependencies to Kubernetes v1.34.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-08-31 15:39:37 +03:00
Stefan Prodan e1fae45113
Merge pull request #956 from fluxcd/dependabot/github_actions/ci-9946de816f
Bump the ci group across 1 directory with 10 updates
2025-08-31 15:01:46 +03:00
dependabot[bot] 4f65ce9f5b
Bump the ci group across 1 directory with 10 updates
Bumps the ci group with 10 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.2.2` | `5.0.0` |
| [korthout/backport-action](https://github.com/korthout/backport-action) | `3.2.0` | `3.3.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.10.0` | `3.11.1` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.17.0` | `6.18.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.4.0` | `3.5.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.7.0` | `5.8.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.8.2` | `3.9.2` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.20.0` | `0.20.5` |
| [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) | `6.3.0` | `6.4.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.18` | `3.29.11` |



Updates `actions/checkout` from 4.2.2 to 5.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](11bd71901b...08c6903cd8)

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

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

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

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

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

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

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

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

Updates `github/codeql-action` from 3.28.18 to 3.29.11
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](ff0a06e83c...3c3833e0f8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
- dependency-name: korthout/backport-action
  dependency-version: 3.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-buildx-action
  dependency-version: 3.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-version: 6.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/login-action
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/metadata-action
  dependency-version: 5.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.9.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-version: 3.29.11
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-31 11:50:22 +00:00
Matheus Pimenta cfbdf5c756
Merge pull request #954 from cappyzawa/feat/object-level-config-validation
Add object-level configuration validation
2025-08-17 17:14:58 +01:00
cappyzawa e954114e1a
Add object-level configuration validation
Validates that ObjectLevelWorkloadIdentity feature gate is enabled
when default service account flags are set. This prevents
misconfiguration where lockdown flags are used without enabling
the required feature gate.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-08-18 00:55:57 +09:00
Matheus Pimenta 3576ac8bc7
Merge pull request #952 from cappyzawa/feat/default-service-account-flag
[RFC-0010] Add default-service-account for lockdown
2025-08-17 09:49:17 +01:00
cappyzawa 1264b490cc
Remove TLS ServerName pinning in TLS config creation
Updates pkg/runtime dependency to v0.80.0 which removes the need for
the insecure parameter in TLSConfigFromSecretRef. This change removes
the forced ServerName pinning behavior that was causing TLS verification
issues, allowing for more flexible certificate validation.

The TLS config creation now relies on the standard Go TLS verification
process without forcing specific ServerName values, improving
compatibility with various certificate configurations.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-08-17 17:40:07 +09:00
cappyzawa f62fa803ef
[RFC-0010] Add default-service-account for lockdown
Add --default-service-account flag for multi-tenant workload identity
lockdown support. This flag sets the default service account name to
be used when .spec.serviceAccountName is not specified in resources.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-08-17 17:40:05 +09:00
dipti-pai efa9671ebc
Merge pull request #950 from dipti-pai/fix-dockerfile
Fix dockerfile after pkg path refactoring
2025-08-15 12:34:25 -07:00
Dipti Pai e4ed952724 Fix dockerfile after pkg path refactoring
Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2025-08-15 12:25:19 -07:00
Stefan Prodan 6955deae42
Merge pull request #947 from abhijith-darshan/feat/gh_app_tls
Add support for mTLS to GitHub App transport
2025-08-14 10:22:45 +03:00
abhijith-darshan 57516b14f7
(chore): adds tls config for GitHub App auth
this commit ensures that if ca.crt or caFile is available in the github app secret, a tls config with user provided certs is appended to system cert pool and passed to the underlying http transport

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): keeps implementation in-sync with source-controller

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): inline proxy detection

This commit removes getProxyOpts(...) helper func and uses pkg/runtime/secrets to retrieve proxy information from secret reference

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): remove err formatting for secrets.ProxyURLFromSecretRef

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>
2025-08-13 16:52:38 +02:00
Stefan Prodan f584731506
Merge pull request #948 from fluxcd/refactor-pkg
Refactor pkg structure
2025-08-11 20:29:20 +03:00
Stefan Prodan 91bbe7491f
Refactor pkg structure
- move pkg/test to internal/testutil
- move pkg/update to internal/update

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-08-11 20:23:26 +03:00
Stefan Prodan 9b8f0a6234
Merge pull request #946 from fluxcd/remove-v1beta1-api
Remove deprecated APIs in group `image.toolkit.fluxcd.io/v1beta1`
2025-08-11 17:55:00 +03:00
Stefan Prodan 8c21b03941
Remove deprecated APIs in group `image.toolkit.fluxcd.io/v1beta1`
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-08-08 16:04:17 +03:00
Matheus Pimenta 3bff81a4e0
Merge pull request #945 from fluxcd/fix-source-index
Fix GitRepository namespace not used in watch index key
2025-08-06 12:21:37 +01:00
Matheus Pimenta 0e29d5342b
Fix GitRepository namespace not used in watch index key
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-08-06 11:48:43 +01:00
Stefan Prodan 03080bae28
Merge pull request #942 from fluxcd/fix-strategy-validation
Make `.spec.update.strategy` optional
2025-07-16 12:49:12 +03:00
Stefan Prodan b81e735bae
Make `.spec.update.strategy` optional
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-07-16 12:34:31 +03:00
Matheus Pimenta 8939b7b5b3
Merge pull request #940 from fluxcd/upgrade-deps
Upgrade Kubernetes to 1.33.2
2025-07-15 09:52:05 +01:00
Matheus Pimenta ecaa7e7b14
Upgrade Kubernetes to 1.33.2
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-07-15 09:45:12 +01:00
Matheus Pimenta 458e0338c3
Merge pull request #931 from cappyzawa/deprecate-updated-template-field
Add deprecation handling for .Updated template field
2025-06-30 14:40:32 +01:00
cappyzawa f1a92cb661
Consolidate Result and ResultV2 types for GA
Remove old Result type and rename ResultV2 to Result, following
Stefan's review feedback to eliminate complex nested structures.
This creates a single, flat Result type containing only FileChanges
for improved API simplicity.

Breaking changes:
- .Changed.ImageResult.Files/.Images/.Objects no longer available
- Users must migrate to .Changed.FileChanges, .Changed.Objects,
  and .Changed.Changes

Enhanced error handling provides specific guidance for removed
template fields, setting Stalled condition with clear migration
instructions. Updated documentation includes removal notes and
migration examples.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-30 22:16:08 +09:00
cappyzawa 7975a00bd1
Add deprecation handling for .Updated template field
Implement error handling for deprecated .Updated template field usage
in ImageUpdateAutomation commit message templates. When users attempt
to use deprecated .Updated fields, the controller now sets a Stalled
condition with a clear error message directing them to use .Changed
fields instead, preventing infinite reconciliation loops.

This prepares for the eventual removal of the .Updated field from the
ImageUpdateAutomation API as part of GA preparation.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-30 22:16:08 +09:00
Matheus Pimenta 7bd947ca9d
Merge pull request #936 from cappyzawa/update-kustomize-v5.7.0
Update kustomize to v5.7.0
2025-06-30 10:46:20 +01:00
cappyzawa 4ff17e6807
Update kustomize dependency to v5.7.0
Upgrade kustomize from v5.6.0 to v5.7.0 to align with the version
used in other Flux components and include latest improvements.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-30 11:11:08 +09:00
Matheus Pimenta aedbb03c3e
Merge pull request #930 from lukas8219/5411-crd-fields
Add better kubectl columns to ImageUpdateAutomation
2025-06-27 17:10:05 +01:00
lukas8219 ad9486eb8d
Add better kubectl columns to ImageUpdateAutomation
Signed-off-by: lukas8219 <lucas.c4d@gmail.com>
2025-06-27 12:49:33 -03:00
Matheus Pimenta b3b47761c6
Merge pull request #929 from cappyzawa/add-imageupdateautomation-shortnames
Add shortNames aliases for ImageUpdateAutomation CRD
2025-06-27 13:15:19 +01:00
cappyzawa af48849cc5
Update ImageUpdateAutomation shortNames to iua,imgupd,imgauto
Changes shortNames from imgupd,imageupdate,imgauto,imageauto
to iua,imgupd,imgauto based on maintainer feedback to limit
the number of aliases and use more concise naming.

Updates both the kubebuilder resource annotation and the
generated CRD manifest.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-27 21:09:00 +09:00
Stefan Prodan ee384d74dd
Merge pull request #934 from fluxcd/release/v0.41.x
Sync changelog for release v0.41.2
2025-06-27 12:23:57 +03:00
Stefan Prodan e7d7d32d93
Merge branch 'main' into release/v0.41.x 2025-06-27 12:18:12 +03:00
Matheus Pimenta c77a9799fb
Merge pull request #928 from felixw7k/main
docs: Add example for opening a PR in Gitea with refspec
2025-06-17 13:16:32 +01:00
Felix Weissbeck fd132e2846 docs: Add example for opening a PR in Gitea with refspec
Signed-off-by: Felix Weissbeck <fe@w7k.de>
2025-06-17 13:57:48 +02:00
Stefan Prodan 124fd9fe8f
Merge pull request #920 from kane8n/git-sparse-checkout-when-update-path-specify
Add support for Git sparse checkout when `.spec.update.path` is specified
2025-06-17 12:59:08 +03:00
kane8n 3999c651b1
SparseCheckout when Spec.Update.Path specified
Signed-off-by: kane8n <takumi.kaneda@zozo.com>
2025-06-17 18:00:07 +09:00
77 changed files with 1164 additions and 1305 deletions

View File

@ -13,11 +13,11 @@ jobs:
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name)) if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs - name: Create backport PRs
uses: korthout/backport-action@436145e922f9561fc5ea157ff406f21af2d6b363 # v3.2.0 uses: korthout/backport-action@ca4972adce8039ff995e618f5fc02d1b7961f27a # v3.3.0
# xref: https://github.com/korthout/backport-action#inputs # xref: https://github.com/korthout/backport-action#inputs
with: with:
# Use token to allow workflows to be triggered for the created PR # Use token to allow workflows to be triggered for the created PR

View File

@ -1,5 +1,6 @@
name: build name: build
on: on:
workflow_dispatch:
pull_request: pull_request:
push: push:
branches: [ 'main', 'release/**' ] branches: [ 'main', 'release/**' ]
@ -12,35 +13,30 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with: with:
go-version: 1.24.x go-version: 1.25.x
cache-dependency-path: | cache-dependency-path: |
**/go.sum **/go.sum
**/go.mod **/go.mod
- name: Setup QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Run tests - name: Run tests
run: make test run: make test
- name: Verify - name: Verify
run: make verify run: make verify
- name: Build multi-arch container image
kind-linux-arm64: uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
runs-on:
group: "ARM64"
steps:
- name: checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with: with:
go-version: 1.24.x push: false
cache-dependency-path: | builder: ${{ steps.buildx.outputs.name }}
**/go.sum context: .
**/go.mod file: ./Dockerfile
- name: Run tests platforms: linux/amd64,linux/arm/v7,linux/arm64
run: make test tags: |
env: ${{ github.repository }}:latest
SKIP_COSIGN_VERIFICATION: true
- name: Verify
run: make verify

View File

@ -11,11 +11,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with: with:
go-version: 1.24.x go-version: 1.25.x
cache-dependency-path: | cache-dependency-path: |
**/go.sum **/go.sum
**/go.mod **/go.mod

View File

@ -1,33 +0,0 @@
name: nightly
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
env:
REPOSITORY: ${{ github.repository }}
permissions:
contents: read # for actions/checkout to fetch code
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Build multi-arch container image
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
push: false
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: |
${{ env.REPOSITORY }}:nightly

View File

@ -29,7 +29,7 @@ jobs:
packages: write # for pushing and signing container images. packages: write # for pushing and signing container images.
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@main uses: fluxcd/pkg/actions/kustomize@main
- name: Prepare - name: Prepare
@ -45,21 +45,21 @@ jobs:
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx - name: Setup Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with: with:
registry: ghcr.io registry: ghcr.io
username: fluxcdbot username: fluxcdbot
password: ${{ secrets.GHCR_TOKEN }} password: ${{ secrets.GHCR_TOKEN }}
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
with: with:
username: fluxcdbot username: fluxcdbot
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }} password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
- name: Generate images meta - name: Generate images meta
id: meta id: meta
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with: with:
images: | images: |
fluxcd/${{ env.CONTROLLER }} fluxcd/${{ env.CONTROLLER }}
@ -68,7 +68,7 @@ jobs:
type=raw,value=${{ steps.prep.outputs.VERSION }} type=raw,value=${{ steps.prep.outputs.VERSION }}
- name: Publish images - name: Publish images
id: build-push id: build-push
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0 uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with: with:
sbom: true sbom: true
provenance: true provenance: true
@ -79,7 +79,7 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64 platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
- uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2 - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
- name: Sign images - name: Sign images
env: env:
COSIGN_EXPERIMENTAL: 1 COSIGN_EXPERIMENTAL: 1
@ -92,11 +92,11 @@ jobs:
mkdir -p config/release mkdir -p config/release
kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml
kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml
- uses: anchore/sbom-action/download-syft@e11c554f704a0b820cbf8c51673f6945e0731532 # v0.20.0 - uses: anchore/sbom-action/download-syft@da167eac915b4e86f08b264dbdbc867b61be6f0c # v0.20.5
- name: Create release and SBOM - name: Create release and SBOM
id: run-goreleaser id: run-goreleaser
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with: with:
version: latest version: latest
args: release --clean --skip=validate args: release --clean --skip=validate

View File

@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Run FOSSA scan and upload build data - name: Run FOSSA scan and upload build data
uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1 uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1
with: with:
@ -31,22 +31,22 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup Go - name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with: with:
go-version: 1.24.x go-version: 1.25.x
cache-dependency-path: | cache-dependency-path: |
**/go.sum **/go.sum
**/go.mod **/go.mod
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 uses: github/codeql-action/init@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
with: with:
languages: go 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://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/ # xref: https://codeql.github.com/codeql-query-help/go/
queries: security-and-quality queries: security-and-quality
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 uses: github/codeql-action/autobuild@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 uses: github/codeql-action/analyze@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11

View File

@ -17,7 +17,7 @@ jobs:
permissions: permissions:
issues: write issues: write
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3 - uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
with: with:
# Configuration file # Configuration file

View File

@ -15,7 +15,7 @@ There are a number of dependencies required to be able to run the controller and
The following dependencies are also used by some of the `make` targets: The following dependencies are also used by some of the `make` targets:
- `controller-gen` (v0.7.0) - `controller-gen` (v0.19.0)
- `gen-crd-api-reference-docs` (v0.3.0) - `gen-crd-api-reference-docs` (v0.3.0)
- `setup-envtest` (latest) - `setup-envtest` (latest)
@ -24,7 +24,7 @@ If any of the above dependencies are not present on your system, the first invoc
## How to run the test suite ## How to run the test suite
Prerequisites: Prerequisites:
* Go >= 1.24 * Go >= 1.25
You can run the test suite by simply doing You can run the test suite by simply doing

View File

@ -1,30 +1,16 @@
ARG BASE_VARIANT=alpine ARG GO_VERSION=1.25
ARG GO_VERSION=1.24
ARG XX_VERSION=1.6.1 ARG XX_VERSION=1.6.1
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} AS gostable # Docker buildkit multi-arch build requires golang alpine
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS builder
FROM gostable AS go-linux
# Build-base consists of build platform dependencies and xx.
# These will be used at current arch to yield execute the cross compilations.
FROM go-${TARGETOS} AS build-base
RUN apk add clang lld
# Copy the build utilities.
COPY --from=xx / / COPY --from=xx / /
# build can still be cached at build platform architecture.
FROM build-base AS build
ARG TARGETPLATFORM ARG TARGETPLATFORM
# Some dependencies have to installed for the target platform:
# https://github.com/tonistiigi/xx#go--cgo
RUN xx-apk add musl-dev gcc
# Configure workspace # Configure workspace
WORKDIR /workspace WORKDIR /workspace
@ -40,34 +26,22 @@ RUN go mod download
# Copy source code # Copy source code
COPY main.go main.go COPY main.go main.go
COPY pkg/ pkg/
COPY internal/ internal/ COPY internal/ internal/
ARG TARGETPLATFORM ARG TARGETPLATFORM
ARG TARGETARCH ARG TARGETARCH
# Reasons why CGO is in use: # build without specifing the arch
# - The SHA1 implementation (sha1cd) used by go-git depends on CGO for ENV CGO_ENABLED=0
# performance reasons. See: https://github.com/pjbgf/sha1cd/issues/15 RUN xx-go build -trimpath -a -o image-automation-controller main.go
ENV CGO_ENABLED=1
RUN export CGO_LDFLAGS="-static -fuse-ld=lld" && \ FROM alpine:3.22
xx-go build \
-ldflags "-s -w" \
-tags 'netgo,osusergo,static_build' \
-o /image-automation-controller -trimpath main.go;
# Ensure that the binary was cross-compiled correctly to the target platform.
RUN xx-verify --static /image-automation-controller
FROM alpine:3.21
ARG TARGETPLATFORM ARG TARGETPLATFORM
RUN apk --no-cache add ca-certificates \ RUN apk --no-cache add ca-certificates \
&& update-ca-certificates && update-ca-certificates
# Copy over binary from build COPY --from=builder /workspace/image-automation-controller /usr/local/bin/
COPY --from=build /image-automation-controller /usr/local/bin/
USER 65534:65534 USER 65534:65534
ENTRYPOINT [ "image-automation-controller" ] ENTRYPOINT [ "image-automation-controller" ]

View File

@ -15,9 +15,6 @@ BUILD_PLATFORMS ?= linux/amd64,linux/arm64,linux/arm/v7
# Allows for defining additional Go test args, e.g. '-tags integration'. # Allows for defining additional Go test args, e.g. '-tags integration'.
GO_TEST_ARGS ?= -race GO_TEST_ARGS ?= -race
# Defines whether cosign verification should be skipped.
SKIP_COSIGN_VERIFICATION ?= false
# Directory with versioned, downloaded things # Directory with versioned, downloaded things
CACHE := cache CACHE := cache
@ -37,16 +34,8 @@ BUILD_DIR := $(REPOSITORY_ROOT)/build
# each fuzzer should run for. # each fuzzer should run for.
FUZZ_TIME ?= 1m FUZZ_TIME ?= 1m
ifeq ($(shell uname -s),Darwin)
GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
endif
ifeq ($(shell uname -s),Linux)
GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
endif
# API (doc) generation utilities # API (doc) generation utilities
CONTROLLER_GEN_VERSION ?= v0.16.1 CONTROLLER_GEN_VERSION ?= v0.19.0
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113 GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
# If gobin not set, create one on ./build and add to path. # If gobin not set, create one on ./build and add to path.
@ -103,15 +92,10 @@ ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml:
curl -s --fail https://raw.githubusercontent.com/fluxcd/image-reflector-controller/${REFLECTOR_VER}/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml \ curl -s --fail https://raw.githubusercontent.com/fluxcd/image-reflector-controller/${REFLECTOR_VER}/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml \
-o ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml -o ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml
check-deps:
ifeq ($(shell uname -s),Darwin)
if ! command -v pkg-config &> /dev/null; then echo "pkg-config is required"; exit 1; fi
endif
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)" KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
test: tidy test-api test_deps generate fmt vet manifests api-docs install-envtest ## Run tests test: tidy test-api test_deps generate fmt vet manifests api-docs install-envtest ## Run tests
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \ KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
go test $(GO_STATIC_FLAGS) $(GO_TEST_ARGS) ./... -coverprofile cover.out go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
test-api: ## Run api tests test-api: ## Run api tests
cd api; go test $(GO_TEST_ARGS) ./... -coverprofile cover.out cd api; go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
@ -120,7 +104,7 @@ manager: generate fmt vet ## Build manager binary
go build -o $(BUILD_DIR)/bin/manager ./main.go go build -o $(BUILD_DIR)/bin/manager ./main.go
run: generate fmt vet manifests # Run against the configured Kubernetes cluster in ~/.kube/config run: generate fmt vet manifests # Run against the configured Kubernetes cluster in ~/.kube/config
go run $(GO_STATIC_FLAGS) ./main.go --log-level=${LOG_LEVEL} --log-encoding=console go run ./main.go --log-level=${LOG_LEVEL} --log-encoding=console
install: manifests ## Install CRDs into a cluster install: manifests ## Install CRDs into a cluster
kustomize build config/crd | kubectl apply -f - kustomize build config/crd | kubectl apply -f -
@ -146,8 +130,8 @@ api-docs: gen-crd-api-reference-docs ## Generate API reference documentation
$(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta2/image-automation.md $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta2/image-automation.md
tidy: ## Run go mod tidy tidy: ## Run go mod tidy
cd api; rm -f go.sum; go mod tidy -compat=1.24 cd api; rm -f go.sum; go mod tidy -compat=1.25
rm -f go.sum; go mod tidy -compat=1.24 rm -f go.sum; go mod tidy -compat=1.25
fmt: ## Run go fmt against code fmt: ## Run go fmt against code
go fmt ./... go fmt ./...
@ -236,9 +220,6 @@ rm -rf $$TMP_DIR ;\
} }
endef endef
update-attributions:
./hack/update-attributions.sh
verify: verify:
ifneq (, $(shell git status --porcelain --untracked-files=no)) ifneq (, $(shell git status --porcelain --untracked-files=no))
@{ \ @{ \

View File

@ -1,32 +1,34 @@
module github.com/fluxcd/image-automation-controller/api module github.com/fluxcd/image-automation-controller/api
go 1.24.0 go 1.25.0
require ( require (
github.com/fluxcd/pkg/apis/meta v1.12.0 github.com/fluxcd/pkg/apis/meta v1.20.0
github.com/fluxcd/source-controller/api v1.6.1 github.com/fluxcd/source-controller/api v1.6.2
k8s.io/apimachinery v0.33.0 k8s.io/apimachinery v0.34.0
sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/controller-runtime v0.22.0
) )
require ( require (
github.com/fluxcd/pkg/apis/acl v0.7.0 // indirect github.com/fluxcd/pkg/apis/acl v0.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/spf13/pflag v1.0.7 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
golang.org/x/net v0.40.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/text v0.25.0 // indirect golang.org/x/net v0.43.0 // indirect
golang.org/x/text v0.28.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
) )

View File

@ -4,19 +4,18 @@ 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.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0= 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/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ=
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg= github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0=
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI= github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
github.com/fluxcd/source-controller/api v1.6.1 h1:ZPTA9lNzBYHmwHfFX978qb8xVkdnQZHF1ggo6BoFm4w= github.com/fluxcd/source-controller/api v1.6.2 h1:UmodAeqLIeF29HdTqf2GiacZyO+hJydJlepDaYsMvhc=
github.com/fluxcd/source-controller/api v1.6.1/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw= github.com/fluxcd/source-controller/api v1.6.2/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/fxamacker/cbor/v2 v2.9.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.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 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.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 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-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.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -33,8 +32,9 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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 h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= 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/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 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
@ -44,16 +44,18 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= 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/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.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= 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/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
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=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -63,26 +65,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-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-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.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-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-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-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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-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.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -94,22 +96,21 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/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 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= 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/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=

View File

@ -14,12 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
// Package v1beta1 contains API types for the image API group, version // Package v1beta1 contains API types for the image v1beta1 API group
// v1beta1. The types here are concerned with automated updates to //
// git, based on metadata from OCI image registries gathered by the // Deprecated: v1beta1 is no longer supported, use v1 instead.
// image-reflector-controller. v1alpha2 did some rearrangement from
// v1alpha1 to make room for future enhancements; v1beta1 does not
// change the schema from v1alpha2.
// //
// +kubebuilder:object:generate=true // +kubebuilder:object:generate=true
// +groupName=image.toolkit.fluxcd.io // +groupName=image.toolkit.fluxcd.io

View File

@ -134,9 +134,7 @@ func SetImageUpdateAutomationReadiness(auto *ImageUpdateAutomation, status metav
} }
// +kubebuilder:object:root=true // +kubebuilder:object:root=true
//+kubebuilder:subresource:status // +kubebuilder:skipversion
//+kubebuilder:deprecatedversion:warning="v1beta1 ImageUpdateAutomation is deprecated, upgrade to v1beta2"
//+kubebuilder:printcolumn:name="Last run",type=string,JSONPath=`.status.lastAutomationRunTime`
// ImageUpdateAutomation is the Schema for the imageupdateautomations API // ImageUpdateAutomation is the Schema for the imageupdateautomations API
type ImageUpdateAutomation struct { type ImageUpdateAutomation struct {

View File

@ -1,7 +1,7 @@
//go:build !ignore_autogenerated //go:build !ignore_autogenerated
/* /*
Copyright 2024 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -36,4 +36,7 @@ const (
// InvalidPolicySelectorReason represents an invalid policy selector. // InvalidPolicySelectorReason represents an invalid policy selector.
InvalidPolicySelectorReason string = "InvalidPolicySelector" InvalidPolicySelectorReason string = "InvalidPolicySelector"
// RemovedTemplateFieldReason represents usage of removed template field.
RemovedTemplateFieldReason string = "RemovedTemplateField"
) )

View File

@ -65,6 +65,7 @@ type CommitSpec struct {
SigningKey *SigningKey `json:"signingKey,omitempty"` SigningKey *SigningKey `json:"signingKey,omitempty"`
// MessageTemplate provides a template for the commit message, // MessageTemplate provides a template for the commit message,
// into which will be interpolated the details of the change made. // into which will be interpolated the details of the change made.
// Note: The `Updated` template field has been removed. Use `Changed` instead.
// +optional // +optional
MessageTemplate string `json:"messageTemplate,omitempty"` MessageTemplate string `json:"messageTemplate,omitempty"`

View File

@ -83,9 +83,9 @@ const (
// inlined here. // inlined here.
type UpdateStrategy struct { type UpdateStrategy struct {
// Strategy names the strategy to be used. // Strategy names the strategy to be used.
// +required // +optional
// +kubebuilder:default=Setters // +kubebuilder:default=Setters
Strategy UpdateStrategyName `json:"strategy"` Strategy UpdateStrategyName `json:"strategy,omitempty"`
// Path to the directory containing the manifests to be updated. // Path to the directory containing the manifests to be updated.
// Defaults to 'None', which translates to the root path // Defaults to 'None', which translates to the root path
@ -132,7 +132,11 @@ type ObservedPolicies map[string]ImageRef
//+kubebuilder:storageversion //+kubebuilder:storageversion
//+kubebuilder:object:root=true //+kubebuilder:object:root=true
//+kubebuilder:subresource:status //+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Last run",type=string,JSONPath=`.status.lastAutomationRunTime` //+kubebuilder:resource:shortName=iua;imgupd;imgauto
//+kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
//+kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
//+kubebuilder:printcolumn:name="Last run",type="string",JSONPath=".status.lastAutomationRunTime",priority=1
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// ImageUpdateAutomation is the Schema for the imageupdateautomations API // ImageUpdateAutomation is the Schema for the imageupdateautomations API
type ImageUpdateAutomation struct { type ImageUpdateAutomation struct {

View File

@ -1,7 +1,7 @@
//go:build !ignore_autogenerated //go:build !ignore_autogenerated
/* /*
Copyright 2024 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition kind: CustomResourceDefinition
metadata: metadata:
annotations: annotations:
controller-gen.kubebuilder.io/version: v0.16.1 controller-gen.kubebuilder.io/version: v0.19.0
name: imageupdateautomations.image.toolkit.fluxcd.io name: imageupdateautomations.image.toolkit.fluxcd.io
spec: spec:
group: image.toolkit.fluxcd.io group: image.toolkit.fluxcd.io
@ -11,326 +11,27 @@ spec:
kind: ImageUpdateAutomation kind: ImageUpdateAutomation
listKind: ImageUpdateAutomationList listKind: ImageUpdateAutomationList
plural: imageupdateautomations plural: imageupdateautomations
shortNames:
- iua
- imgupd
- imgauto
singular: imageupdateautomation singular: imageupdateautomation
scope: Namespaced scope: Namespaced
versions: versions:
- additionalPrinterColumns: - additionalPrinterColumns:
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
- jsonPath: .status.lastAutomationRunTime - jsonPath: .status.lastAutomationRunTime
name: Last run name: Last run
priority: 1
type: string type: string
deprecated: true - jsonPath: .metadata.creationTimestamp
deprecationWarning: v1beta1 ImageUpdateAutomation is deprecated, upgrade to v1beta2 name: Age
name: v1beta1 type: date
schema:
openAPIV3Schema:
description: ImageUpdateAutomation is the Schema for the imageupdateautomations
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation
properties:
git:
description: |-
GitSpec contains all the git-specific definitions. This is
technically optional, but in practice mandatory until there are
other kinds of source allowed.
properties:
checkout:
description: |-
Checkout gives the parameters for cloning the git repository,
ready to make changes. If not present, the `spec.ref` field from the
referenced `GitRepository` or its default will be used.
properties:
ref:
description: |-
Reference gives a branch, tag or commit to clone from the Git
repository.
properties:
branch:
description: Branch to check out, defaults to 'master'
if no other field is defined.
type: string
commit:
description: |-
Commit SHA to check out, takes precedence over all reference fields.
This can be combined with Branch to shallow clone the branch, in which
the commit is expected to exist.
type: string
name:
description: |-
Name of the reference to check out; takes precedence over Branch, Tag and SemVer.
It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description
Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head"
type: string
semver:
description: SemVer tag expression to check out, takes
precedence over Tag.
type: string
tag:
description: Tag to check out, takes precedence over Branch.
type: string
type: object
required:
- ref
type: object
commit:
description: Commit specifies how to commit to the git repository.
properties:
author:
description: |-
Author gives the email and optionally the name to use as the
author of commits.
properties:
email:
description: Email gives the email to provide when making
a commit.
type: string
name:
description: Name gives the name to provide when making
a commit.
type: string
required:
- email
type: object
messageTemplate:
description: |-
MessageTemplate provides a template for the commit message,
into which will be interpolated the details of the change made.
type: string
signingKey:
description: SigningKey provides the option to sign commits
with a GPG key
properties:
secretRef:
description: |-
SecretRef holds the name to a secret that contains a 'git.asc' key
corresponding to the ASCII Armored file containing the GPG signing
keypair as the value. It must be in the same namespace as the
ImageUpdateAutomation.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
required:
- secretRef
type: object
required:
- author
type: object
push:
description: |-
Push specifies how and where to push commits made by the
automation. If missing, commits are pushed (back) to
`.spec.checkout.branch` or its default.
properties:
branch:
description: |-
Branch specifies that commits should be pushed to the branch
named. The branch is created using `.spec.checkout.branch` as the
starting point, if it doesn't already exist.
type: string
options:
additionalProperties:
type: string
description: |-
Options specifies the push options that are sent to the Git
server when performing a push operation. For details, see:
https://git-scm.com/docs/git-push#Documentation/git-push.txt---push-optionltoptiongt
type: object
refspec:
description: |-
Refspec specifies the Git Refspec to use for a push operation.
If both Branch and Refspec are provided, then the commit is pushed
to the branch and also using the specified refspec.
For more details about Git Refspecs, see:
https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
type: string
type: object
required:
- commit
type: object
interval:
description: |-
Interval gives an lower bound for how often the automation
run should be attempted.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
sourceRef:
description: |-
SourceRef refers to the resource giving access details
to a git repository.
properties:
apiVersion:
description: API version of the referent.
type: string
kind:
default: GitRepository
description: Kind of the referent.
enum:
- GitRepository
type: string
name:
description: Name of the referent.
type: string
namespace:
description: Namespace of the referent, defaults to the namespace
of the Kubernetes resource object that contains the reference.
type: string
required:
- kind
- name
type: object
suspend:
description: |-
Suspend tells the controller to not run this automation, until
it is unset (or set to false). Defaults to false.
type: boolean
update:
default:
strategy: Setters
description: |-
Update gives the specification for how to update the files in
the repository. This can be left empty, to use the default
value.
properties:
path:
description: |-
Path to the directory containing the manifests to be updated.
Defaults to 'None', which translates to the root path
of the GitRepositoryRef.
type: string
strategy:
default: Setters
description: Strategy names the strategy to be used.
enum:
- Setters
type: string
required:
- strategy
type: object
required:
- interval
- sourceRef
type: object
status:
default:
observedGeneration: -1
description: ImageUpdateAutomationStatus defines the observed state of
ImageUpdateAutomation
properties:
conditions:
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastAutomationRunTime:
description: |-
LastAutomationRunTime records the last time the controller ran
this automation through to completion (even if no updates were
made).
format: date-time
type: string
lastHandledReconcileAt:
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
lastPushCommit:
description: |-
LastPushCommit records the SHA1 of the last commit made by the
controller, for this automation object
type: string
lastPushTime:
description: LastPushTime records the time of the last pushed change.
format: date-time
type: string
observedGeneration:
format: int64
type: integer
type: object
type: object
served: true
storage: false
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .status.lastAutomationRunTime
name: Last run
type: string
name: v1beta2 name: v1beta2
schema: schema:
openAPIV3Schema: openAPIV3Schema:
@ -426,6 +127,7 @@ spec:
description: |- description: |-
MessageTemplate provides a template for the commit message, MessageTemplate provides a template for the commit message,
into which will be interpolated the details of the change made. into which will be interpolated the details of the change made.
Note: The `Updated` template field has been removed. Use `Changed` instead.
type: string type: string
messageTemplateValues: messageTemplateValues:
additionalProperties: additionalProperties:
@ -593,8 +295,6 @@ spec:
enum: enum:
- Setters - Setters
type: string type: string
required:
- strategy
type: object type: object
required: required:
- interval - interval

View File

@ -1,29 +0,0 @@
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
name: imageupdateautomation-sample
spec:
interval: 5m
sourceRef:
kind: GitRepository # the only valid value, but good practice to be explicit here
name: sample-repo
git:
checkout:
ref:
branch: main
commit:
author:
name: fluxbot
email: fluxbot@example.com
messageTemplate: |
An automated update from FluxBot
[ci skip]
signingKey:
secretRef:
name: git-pgp
push:
branch: auto
update:
strategy: Setters
path: ./cluster/sample

View File

@ -67,7 +67,8 @@ string
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>MessageTemplate provides a template for the commit message, <p>MessageTemplate provides a template for the commit message,
into which will be interpolated the details of the change made.</p> into which will be interpolated the details of the change made.
Note: The <code>Updated</code> template field has been removed. Use <code>Changed</code> instead.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -873,6 +874,7 @@ UpdateStrategyName
</em> </em>
</td> </td>
<td> <td>
<em>(Optional)</em>
<p>Strategy names the strategy to be used.</p> <p>Strategy names the strategy to be used.</p>
</td> </td>
</tr> </tr>

View File

@ -374,12 +374,12 @@ spec:
Automated image update by Flux Automated image update by Flux
``` ```
**Deprecation Note:** The `Updated` template data available in v1beta1 API is **Removal Note:** The `Updated` template data has been removed from the API.
deprecated. `Changed` template data is recommended for template data, as it Use `Changed` template data instead, as it accommodates for all the updates,
accommodates for all the updates, including partial updates to just the image including partial updates to just the image name or the tag, not just full image
name or the tag, not just full image with name and tag update. The old templates with name and tag update. Templates using `Updated` will result in an error and
will continue to work in v1beta2 API as `Updated` has not been removed yet. In the ImageUpdateAutomation will be marked as Stalled.
the next API version, `Updated` may be removed.
The message template also has access to the data related to the changes made by The message template also has access to the data related to the changes made by
the automation. The template is a [Go text template][go-text-template]. The data the automation. The template is a [Go text template][go-text-template]. The data
@ -393,14 +393,14 @@ type TemplateData struct {
AutomationObject struct { AutomationObject struct {
Name, Namespace string Name, Namespace string
} }
Changed update.ResultV2 Changed update.Result
Values map[string]string Values map[string]string
} }
// ResultV2 contains the file changes made during the update. It contains // Result contains the file changes made during the update. It contains
// details about the exact changes made to the files and the objects in them. It // details about the exact changes made to the files and the objects in them. It
// has a nested structure file->objects->changes. // has a nested structure file->objects->changes.
type ResultV2 struct { type Result struct {
FileChanges map[string]ObjectChanges FileChanges map[string]ObjectChanges
} }
@ -427,10 +427,10 @@ over the changed objects and changes:
```go ```go
// Changes returns all the changes that were made in at least one update. // Changes returns all the changes that were made in at least one update.
func (r ResultV2) Changes() []Change func (r Result) Changes() []Change
// Objects returns ObjectChanges, regardless of which file they appear in. // Objects returns ObjectChanges, regardless of which file they appear in.
func (r ResultV2) Objects() ObjectChanges func (r Result) Objects() ObjectChanges
``` ```
Example of using the methods in a template: Example of using the methods in a template:
@ -558,7 +558,13 @@ destination reference. An example of a valid refspec is
If both `.push.refspec` and `.push.branch` are specified, then the reconciler If both `.push.refspec` and `.push.branch` are specified, then the reconciler
will push to both the destinations. This is particularly useful for working with will push to both the destinations. This is particularly useful for working with
Gerrit servers. For more information about this, please refer to the Gerrit servers. For more information about this, please refer to the
[Gerrit](#gerrit) section. [Gerrit](#gerrit) section. This can also be used to automatically open
Pull-Requests in Gitea or Forgejo. See the [Gitea](#gitea) section for
an example.
If only `.push.refspec` is set, without explicitly defining a `.push.branch`, the
controller falls back to pushing to the branch from `checkoutRef` and *also*
pushes to `.push.refspec`.
**Note:** If both `.push.refspec` and `.push.branch` are essentially equal to **Note:** If both `.push.refspec` and `.push.branch` are essentially equal to
each other (for e.g.: `.push.refspec: refs/heads/main:refs/heads/main` and each other (for e.g.: `.push.refspec: refs/heads/main:refs/heads/main` and
@ -958,6 +964,42 @@ image tag to a different one, it leads to a distinct Change-Id for the commit.
Consequently, this action will trigger the creation of an additional Change, Consequently, this action will trigger the creation of an additional Change,
even when an existing Change containing outdated modifications remains open. even when an existing Change containing outdated modifications remains open.
#### Gitea
[Gitea](https://docs.gitea.com/usage/agit) and [Forgejo](https://forgejo.org/docs/latest/user/agit-support/) each implement the AGit-Workflow.
This means, the image-automation-controller is able to open a pull-request by
pushing to a `refspec` like `HEAD:refs/for/main` with the apropriate [push-options](#push-options).
The following example opens a PR on a Gitea or Forgejo-Server:
```yaml
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: my-automation
namespace: flux-system
spec:
git:
checkout:
ref:
branch: main
push:
branch: flux-updates
refspec: refs/heads/flux-updates:refs/for/main
options:
topic: flux-updates
title: Flux Image Update
description: |-
This PR is automatically opened by the fluxcd *image-automation-controller*
commit:
author:
email: flux@eaample.com
name: fluxcd
messageTemplate: '{{range .Changed.Changes}}{{print .OldValue}} -> {{println
.NewValue}}{{end}}'
```
## ImageUpdateAutomation Status ## ImageUpdateAutomation Status
### Observed Policies ### Observed Policies

178
go.mod
View File

@ -1,96 +1,103 @@
module github.com/fluxcd/image-automation-controller module github.com/fluxcd/image-automation-controller
go 1.24.0 go 1.25.0
replace github.com/fluxcd/image-automation-controller/api => ./api replace github.com/fluxcd/image-automation-controller/api => ./api
// Pin kustomize to v5.6.0 // Pin kustomize to v5.7.1
replace ( replace (
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.19.0 sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.20.1
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.19.0 sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.20.1
) )
require ( require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
github.com/Masterminds/sprig/v3 v3.3.0 github.com/Masterminds/sprig/v3 v3.3.0
github.com/ProtonMail/go-crypto v1.2.0 github.com/ProtonMail/go-crypto v1.3.0
github.com/cyphar/filepath-securejoin v0.4.1 github.com/cyphar/filepath-securejoin v0.4.1
github.com/fluxcd/image-automation-controller/api v0.41.2 github.com/fluxcd/image-automation-controller/api v0.41.2
github.com/fluxcd/image-reflector-controller/api v0.35.2 github.com/fluxcd/image-reflector-controller/api v0.35.2
github.com/fluxcd/pkg/apis/acl v0.7.0 github.com/fluxcd/pkg/apis/acl v0.9.0
github.com/fluxcd/pkg/apis/event v0.17.0 github.com/fluxcd/pkg/apis/event v0.19.0
github.com/fluxcd/pkg/apis/meta v1.12.0 github.com/fluxcd/pkg/apis/meta v1.20.0
github.com/fluxcd/pkg/auth v0.17.0 github.com/fluxcd/pkg/auth v0.29.0
github.com/fluxcd/pkg/cache v0.9.0 github.com/fluxcd/pkg/cache v0.11.0
github.com/fluxcd/pkg/git v0.32.0 github.com/fluxcd/pkg/git v0.36.0
github.com/fluxcd/pkg/git/gogit v0.35.1 github.com/fluxcd/pkg/git/gogit v0.40.0
github.com/fluxcd/pkg/gittestserver v0.17.0 github.com/fluxcd/pkg/gittestserver v0.20.0
github.com/fluxcd/pkg/runtime v0.60.0 github.com/fluxcd/pkg/runtime v0.82.0
github.com/fluxcd/pkg/ssh v0.19.0 github.com/fluxcd/pkg/ssh v0.21.0
github.com/fluxcd/source-controller/api v1.6.1 github.com/fluxcd/source-controller/api v1.6.2
github.com/go-git/go-billy/v5 v5.6.2 github.com/go-git/go-billy/v5 v5.6.2
github.com/go-git/go-git/v5 v5.16.2 github.com/go-git/go-git/v5 v5.16.2
github.com/go-logr/logr v1.4.2 github.com/go-logr/logr v1.4.3
github.com/google/go-containerregistry v0.20.3 github.com/google/go-containerregistry v0.20.6
github.com/onsi/gomega v1.37.0 github.com/onsi/gomega v1.38.2
github.com/otiai10/copy v1.14.1 github.com/otiai10/copy v1.14.1
github.com/spf13/pflag v1.0.6 github.com/spf13/pflag v1.0.7
k8s.io/api v0.33.0 k8s.io/api v0.34.0
k8s.io/apimachinery v0.33.0 k8s.io/apimachinery v0.34.0
k8s.io/client-go v0.33.0 k8s.io/client-go v0.34.0
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/controller-runtime v0.22.0
sigs.k8s.io/kustomize/kyaml v0.19.0 sigs.k8s.io/kustomize/kyaml v0.20.1
) )
require ( require (
cloud.google.com/go/compute/metadata v0.6.0 // indirect cloud.google.com/go/auth v0.16.5 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.8.0 // indirect
dario.cat/mergo v1.0.1 // indirect dario.cat/mergo v1.0.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // 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/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.0 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect github.com/aws/aws-sdk-go-v2 v1.38.3 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect github.com/aws/aws-sdk-go-v2/config v1.31.6 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.18.10 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 // indirect github.com/aws/aws-sdk-go-v2/service/ecr v1.50.1 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.0 // indirect github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect github.com/aws/aws-sdk-go-v2/service/eks v1.73.1 // 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/accept-encoding v1.13.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 // indirect
github.com/aws/smithy-go v1.22.2 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 // indirect
github.com/aws/smithy-go v1.23.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect
github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.16.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.3 // indirect github.com/chai2010/gettext-go v1.0.3 // indirect
github.com/cloudflare/circl v1.6.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v27.5.0+incompatible // indirect github.com/docker/cli v28.2.2+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fluxcd/cli-utils v0.36.0-flux.13 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fluxcd/cli-utils v0.36.0-flux.15 // indirect
github.com/fluxcd/gitkit v0.6.0 // indirect github.com/fluxcd/gitkit v0.6.0 // indirect
github.com/fluxcd/pkg/version v0.7.0 // indirect github.com/fluxcd/pkg/version v0.10.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-errors/errors v1.5.1 // 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/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect
@ -98,19 +105,21 @@ require (
github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/google/btree v1.1.3 // indirect github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.9 // indirect github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-github/v71 v71.0.0 // indirect github.com/google/go-github/v72 v72.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/s2a-go v0.1.9 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/huandu/xstrings v1.5.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@ -127,20 +136,21 @@ require (
github.com/moby/spdystream v0.5.0 // indirect github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/term v0.5.2 // indirect github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/otiai10/mint v1.6.3 // indirect github.com/otiai10/mint v1.6.3 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/pjbgf/sha1cd v0.4.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.63.0 // indirect github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect github.com/prometheus/procfs v0.17.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shopspring/decimal v1.4.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect
@ -151,30 +161,40 @@ require (
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xlab/treeprint v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.39.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/net v0.40.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/oauth2 v0.29.0 // indirect golang.org/x/crypto v0.41.0 // indirect
golang.org/x/sync v0.15.0 // indirect golang.org/x/net v0.43.0 // indirect
golang.org/x/sys v0.33.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/term v0.32.0 // indirect golang.org/x/sync v0.16.0 // indirect
golang.org/x/text v0.26.0 // indirect golang.org/x/sys v0.35.0 // indirect
golang.org/x/time v0.11.0 // indirect golang.org/x/term v0.34.0 // indirect
golang.org/x/text v0.28.0 // indirect
golang.org/x/time v0.12.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect google.golang.org/api v0.248.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect
google.golang.org/grpc v1.74.2 // indirect
google.golang.org/protobuf v1.36.7 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.33.0 // indirect k8s.io/apiextensions-apiserver v0.34.0 // indirect
k8s.io/cli-runtime v0.33.0 // indirect k8s.io/cli-runtime v0.34.0 // indirect
k8s.io/component-base v0.33.0 // indirect k8s.io/component-base v0.34.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kubectl v0.33.0 // indirect k8s.io/kubectl v0.34.0 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/kustomize/api v0.19.0 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect sigs.k8s.io/yaml v1.6.0 // indirect
) )

373
go.sum
View File

@ -1,17 +1,25 @@
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
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.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA=
cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw=
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
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 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= 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.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 h1:ci6Yd6nysBRLEodoziB6ah1+YOzZbZk+NYneoA6q+6E=
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/azcore v1.19.0/go.mod h1:QyVsSSN64v5TGltphKLQ2sQxe4OBQg0J1eKRcVBnfgE=
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.11.0 h1:MhRfI58HblXzCtWEZCO0feHs8LweePB3s90r7WaR1KU=
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 v1.11.0/go.mod h1:okZ+ZURbArNdlJ+ptXoyHNuOETzOl1Oww19rm8I2WLA=
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 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/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/containers/azcontainerregistry v0.2.3 h1:ldKsKtEIblsgsr6mPwrd9yRntoX6uLz/K89wsldwx/k=
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/containers/azcontainerregistry v0.2.3/go.mod h1:MAm7bk0oDLmD8yIkvfbxPW04fxzphPyL+7GzwHxOp6Y=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 h1:figxyQZXzZQIcP3njhC68bYUiTw45J8/SsHaLW8Ax0M=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0/go.mod h1:TmlMW4W5OvXOmOyKNnor8nlMMiO1ctIyzmHme/VHsrA=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= 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/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 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
@ -22,63 +30,65 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs= github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= github.com/aws/aws-sdk-go-v2 v1.38.3 h1:B6cV4oxnMs45fql4yRH+/Po/YU+597zgWqvDpYMturk=
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= github.com/aws/aws-sdk-go-v2 v1.38.3/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM= github.com/aws/aws-sdk-go-v2/config v1.31.6 h1:a1t8fXY4GT4xjyJExz4knbuoxSCacB5hT/WgtfPyLjo=
github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g= github.com/aws/aws-sdk-go-v2/config v1.31.6/go.mod h1:5ByscNi7R+ztvOGzeUaIu49vkMk2soq5NaH5PYe33MQ=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM= github.com/aws/aws-sdk-go-v2/credentials v1.18.10 h1:xdJnXCouCx8Y0NncgoptztUocIYLKeQxrCgN6x9sdhg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ= github.com/aws/aws-sdk-go-v2/credentials v1.18.10/go.mod h1:7tQk08ntj914F/5i9jC4+2HQTAuJirq7m1vZVIhEkWs=
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.18.6 h1:wbjnrrMnKew78/juW7I2BtKQwa1qlf6EjQgS69uYY14=
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/ec2/imds v1.18.6/go.mod h1:AtiqqNrDioJXuUgz3+3T0mBWN7Hro2n9wll2zRUc0ww=
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.4.6 h1:uF68eJA6+S9iVr9WgX1NaRGyQ/6MdIyc4JNUo6TN1FA=
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/configsources v1.4.6/go.mod h1:qlPeVZCGPiobx8wb1ft0GHT5l+dc6ldnwInDFaMvC7Y=
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.7.6 h1:pa1DEC6JoI0zduhZePp3zmhWvk/xxm4NB8Hy/Tlsgos=
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/endpoints/v2 v2.7.6/go.mod h1:gxEjPebnhWGJoaDdtDkA0JX46VRg1wcTHYe63OfX5pE=
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 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/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
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.50.1 h1:lcwFjRx3C/hBxJzoWkD6DIG2jeB+mzLmFVBFVOadxxE=
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/ecr v1.50.1/go.mod h1:qt9OL5kXqWoSub4QAkOF74mS3M2zOTNxMODqgwEUjt8=
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.0 h1:wA2O6pZ2r5smqJunFP4hp7qptMW4EQxs8O6RVHPulOE= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2 h1:EfatDVSMFxaS5TiR0C0zssQU1Nm+rGx3VbUGIH1y274=
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.0/go.mod h1:RZL7ov7c72wSmoM8bIiVxRHgcVdzhNkVW2J36C8RF4s= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2/go.mod h1:oRy1IEgzXtOkEk4B/J7HZbXUC258drDLtkmc++lN7IA=
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/eks v1.73.1 h1:Txq5jxY/ao+2Vx/kX9+65WTqkzCnxSlXnwIj+Cr/fng=
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/eks v1.73.1/go.mod h1:+hYFg3laewH0YCfJRv+o5R3bradDKmFIm/uaiaD1U7U=
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/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM=
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/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 h1:LHS1YAIJXJ4K9zS+1d/xa9JAA9sL2QyXIQCQFQW/X08=
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/internal/presigned-url v1.13.6/go.mod h1:c9PCiTEuh0wQID5/KqA32J+HAgZxN9tOGXKCiYJjTZI=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako= github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 h1:8OLZnVJPvjnrxEwHFg9hVUof/P4sibH+Ea4KKuqAGSg=
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/sso v1.29.1/go.mod h1:27M3BpVi0C02UiQh1w9nsBEit6pLhlaH3NHna6WUbDE=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 h1:gKWSTnqudpo8dAxqBqZnDoDWCiEh/40FziUjr/mo6uA=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2/go.mod h1:x7+rkNmRoEN1U13A6JE2fXne9EWyJy54o3n6d4mGaXQ=
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 h1:YZPjhyaGzhDQEvsffDEcpycq49nl7fiGcfJTIo8BszI=
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/aws/aws-sdk-go-v2/service/sts v1.38.2/go.mod h1:2dIN8qhQfv37BdUYGgEC8Q3tteM3zFxTI1MLO2O3J3c=
github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 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/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= 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/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 h1:7r2rPUM04rgszMP0U1UZ1M5VoVVIlsaBSnpABfYxcQY= github.com/bradleyfalzon/ghinstallation/v2 v2.16.0 h1:B91r9bHtXp/+XRgS5aZm6ZzTdz3ahgJYmkt4xZkgDz8=
github.com/bradleyfalzon/ghinstallation/v2 v2.15.0/go.mod h1:PoH9Vhy82OeRFZfxsVrk3mfQhVkEzou9OOwPOsEhiXE= github.com/bradleyfalzon/ghinstallation/v2 v2.16.0/go.mod h1:OeVe5ggFzoBnmgitZe/A+BqGOnv1DvU/0uiLQi1wutM=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 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/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80= 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/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 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk= github.com/coreos/go-oidc/v3 v3.15.0 h1:R6Oz8Z4bqWR7VFQ+sPSvZPQv4x8M+sJkDO5ojgwlyAg=
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= github.com/coreos/go-oidc/v3 v3.15.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
@ -88,12 +98,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v27.5.0+incompatible h1:aMphQkcGtpHixwwhAXJT1rrK/detk2JIvDaFkLctbGM= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
github.com/docker/cli v27.5.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
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/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
@ -108,42 +116,44 @@ github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fluxcd/cli-utils v0.36.0-flux.13 h1:2X5yjz/rk9mg7+bMFBDZKGKzeZpAmY2s6iwbNZz7OzM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/fluxcd/cli-utils v0.36.0-flux.13/go.mod h1:b2iSoIeDTtjfCB0IKtGgqlhhvWa1oux3e90CjOf81oA= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fluxcd/cli-utils v0.36.0-flux.15 h1:Et5QLnIpRjj+oZtM9gEybkAaoNsjysHq0y1253Ai94Y=
github.com/fluxcd/cli-utils v0.36.0-flux.15/go.mod h1:AqRUmWIfNE7cdL6NWSGF0bAlypGs+9x5UQ2qOtlEzv4=
github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg= github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg=
github.com/fluxcd/gitkit v0.6.0/go.mod h1:svOHuKi0fO9HoawdK4HfHAJJseZDHHjk7I3ihnCIqNo= github.com/fluxcd/gitkit v0.6.0/go.mod h1:svOHuKi0fO9HoawdK4HfHAJJseZDHHjk7I3ihnCIqNo=
github.com/fluxcd/image-reflector-controller/api v0.35.2 h1:EzjtUpyx8kbTFx7ugdi5LRMaCpQW4kX/vjFCIPpPD38= github.com/fluxcd/image-reflector-controller/api v0.35.2 h1:EzjtUpyx8kbTFx7ugdi5LRMaCpQW4kX/vjFCIPpPD38=
github.com/fluxcd/image-reflector-controller/api v0.35.2/go.mod h1:mjpokoQhFs2RxfFjY4rHpn3ZAUvee8TiELyROFN4wiA= github.com/fluxcd/image-reflector-controller/api v0.35.2/go.mod h1:mjpokoQhFs2RxfFjY4rHpn3ZAUvee8TiELyROFN4wiA=
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0= github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA=
github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ= github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
github.com/fluxcd/pkg/apis/event v0.17.0 h1:foEINE++pCJlWVhWjYDXfkVmGKu8mQ4BDBlbYi5NU7M= github.com/fluxcd/pkg/apis/event v0.19.0 h1:ZJU2voontkzp5rNYA4JMOu40S4tRcrWi4Do59EnyFwg=
github.com/fluxcd/pkg/apis/event v0.17.0/go.mod h1:0fLhLFiHlRTDKPDXdRnv+tS7mCMIQ0fJxnEfmvGM/5A= github.com/fluxcd/pkg/apis/event v0.19.0/go.mod h1:deuIyUb6lh+Z1Ccvwwxhm1wNM3kpSo+vF1IgRnpaZfQ=
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg= github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0=
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI= github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
github.com/fluxcd/pkg/auth v0.17.0 h1:jgum55f5K7Db6yI2bi4WeKojTzQS9KxlHCC0CsFs5x8= github.com/fluxcd/pkg/auth v0.29.0 h1:lLc63zjodqIqg5ydlU/Kp3Qa+wvh6G2khjop5MHALvk=
github.com/fluxcd/pkg/auth v0.17.0/go.mod h1:4h6s8VBNuec3tWd4xIReLw8BYPOKaIegjNMEbA4ikTU= github.com/fluxcd/pkg/auth v0.29.0/go.mod h1:bjZ+6RMSGgsQQK+aPfVP8HWuBbb+FLlFxMiqd8ywzik=
github.com/fluxcd/pkg/cache v0.9.0 h1:EGKfOLMG3fOwWnH/4Axl5xd425mxoQbZzlZoLfd8PDk= github.com/fluxcd/pkg/cache v0.11.0 h1:fsE8S+una21fSNw4MDXGUIf0Gf1J+pqa4RbsVKf2aTI=
github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU= github.com/fluxcd/pkg/cache v0.11.0/go.mod h1:2RTIU6PsJniHmfnllQWFEo7fa5V8KQlnMgn4o0sme40=
github.com/fluxcd/pkg/git v0.32.0 h1:agSE4Ia8saj5eg075qhLhZvjuTg/Hnj8mZU0meGKOyc= github.com/fluxcd/pkg/git v0.36.0 h1:oakFKxTX5yiLcFzCS1SaV+mMXaODaF1Ic6/oCLfIe7I=
github.com/fluxcd/pkg/git v0.32.0/go.mod h1:rUgLXVQGBkBggHOLVMhHMHaweQ8Oc6HwZiN2Zm08Zxs= github.com/fluxcd/pkg/git v0.36.0/go.mod h1:4TgfjcoM3B2sGsO5VbfBSwJQYzNCONGihcTOW8P3Jxw=
github.com/fluxcd/pkg/git/gogit v0.35.1 h1:NZI7rWDUUaGhEqgbvlh2CK9UZU/eteQ3eDTEMvdHmBo= github.com/fluxcd/pkg/git/gogit v0.40.0 h1:VCsHC1440jMk1wAGWCwkgU2nDUBOPeYbCk6/OtvbY7Y=
github.com/fluxcd/pkg/git/gogit v0.35.1/go.mod h1:/WcAqTDBrjF+6cwFTaK7kNM791j/pXmw0fy8xbd1YWo= github.com/fluxcd/pkg/git/gogit v0.40.0/go.mod h1:nQVyfa+rYSeVQiwVH5f/C4o1sf2MtMFjMlt3VSkC+P0=
github.com/fluxcd/pkg/gittestserver v0.17.0 h1:JlBvWZQTDOI+np5Z+084m3DkeAH1hMusEybyRUDF63k= github.com/fluxcd/pkg/gittestserver v0.20.0 h1:xhzLV89mta23ZvTK0cpDCR6ni6vp5Di+9b4v3YBziMQ=
github.com/fluxcd/pkg/gittestserver v0.17.0/go.mod h1:E/40EmLoXcMqd6gLuLDC9F6KJxqHVGbBBeMNKk5XdxU= github.com/fluxcd/pkg/gittestserver v0.20.0/go.mod h1:vGmM9eDJk56gx+osTcSHeScefnAaL4czR+rsNsvh0nw=
github.com/fluxcd/pkg/runtime v0.60.0 h1:d++EkV3FlycB+bzakB5NumwY4J8xts8i7lbvD6jBLeU= github.com/fluxcd/pkg/runtime v0.82.0 h1:VdPPRJtj8/rcBdqY7GZSffoxe5elFHt+ymwQHNbPOlc=
github.com/fluxcd/pkg/runtime v0.60.0/go.mod h1:UeU0/eZLErYC/1bTmgzBfNXhiHy9fuQzjfLK0HxRgxY= github.com/fluxcd/pkg/runtime v0.82.0/go.mod h1:rIDynMhU5upbn8ce3bXQhH5L6vtDw5MELycvtJG/+og=
github.com/fluxcd/pkg/ssh v0.19.0 h1:njSwNJQZ+3TGhBXshU/2TbqvooMbf6lQzFn7w6vuaKI= github.com/fluxcd/pkg/ssh v0.21.0 h1:ZmyF0n9je0cTTkOpvFVgIhmdx9qtswnVE60TK4IzJh0=
github.com/fluxcd/pkg/ssh v0.19.0/go.mod h1:0e7sqpyekj65A4y/UUCVUxxVw8HonwFtJJ2KhvJQq1o= github.com/fluxcd/pkg/ssh v0.21.0/go.mod h1:nX+gvJOmjf0E7lxq5mKKzDIdPEL2jOUQZbkBMS+mDtk=
github.com/fluxcd/pkg/version v0.7.0 h1:jZT5I6WFy1KlM40nHCSqlHmjC1VT1/DfmbAdOkIVVJc= github.com/fluxcd/pkg/version v0.10.0 h1:WETlCRbfbocsDItkCCeh/4x4zQkZ5i/lUe7P7VaQBrI=
github.com/fluxcd/pkg/version v0.7.0/go.mod h1:3BjQDJXIZJmeJLXnfa2yG/sNAT1t5oeLAPfnSjOHNuA= github.com/fluxcd/pkg/version v0.10.0/go.mod h1:dgmjEq4ykvBnqK1oVXM+hcXx3kAY/b4uZDYUn8XnHjk=
github.com/fluxcd/source-controller/api v1.6.1 h1:ZPTA9lNzBYHmwHfFX978qb8xVkdnQZHF1ggo6BoFm4w= github.com/fluxcd/source-controller/api v1.6.2 h1:UmodAeqLIeF29HdTqf2GiacZyO+hJydJlepDaYsMvhc=
github.com/fluxcd/source-controller/api v1.6.1/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw= github.com/fluxcd/source-controller/api v1.6.2/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= 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/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.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
@ -158,8 +168,11 @@ github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
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 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
@ -176,33 +189,38 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= 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/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
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 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 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-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.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI= github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
github.com/google/go-github/v71 v71.0.0 h1:Zi16OymGKZZMm8ZliffVVJ/Q9YZreDKONCr+WUd0Z30= github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM=
github.com/google/go-github/v71 v71.0.0/go.mod h1:URZXObp2BLlMjwu0O8g4y6VBneUj2bCHgnI8FfgZ51M= github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 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/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= 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/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
@ -211,8 +229,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@ -263,18 +281,19 @@ github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFL
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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 h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/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 h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= github.com/onsi/ginkgo/v2 v2.25.2 h1:hepmgwx1D+llZleKQDMEvy8vIlCxMGt7W5ZxDjIEhsw=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= github.com/onsi/ginkgo/v2 v2.25.2/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
@ -283,8 +302,8 @@ github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY=
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -292,16 +311,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= 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/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.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
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 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 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 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@ -319,8 +336,9 @@ github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk=
github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= 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/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
@ -329,8 +347,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= 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/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
@ -339,6 +357,20 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
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/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= 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/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 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@ -347,12 +379,16 @@ 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/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 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= 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.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -360,15 +396,15 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/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.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= 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-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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.16.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-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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -380,32 +416,42 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/time v0.12.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-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-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-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.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/api v0.248.0 h1:hUotakSkcwGdYUqzCRc5yGYsg4wXxpkKlW5ryVqvC1Y=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= google.golang.org/api v0.248.0/go.mod h1:yAFUAF56Li7IuIQbTFoLwXTCI6XCFKueOlS7S9e4F9k=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
@ -423,38 +469,37 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc=
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0=
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
k8s.io/cli-runtime v0.33.0 h1:Lbl/pq/1o8BaIuyn+aVLdEPHVN665tBAXUePs8wjX7c= k8s.io/cli-runtime v0.34.0 h1:N2/rUlJg6TMEBgtQ3SDRJwa8XyKUizwjlOknT1mB2Cw=
k8s.io/cli-runtime v0.33.0/go.mod h1:QcA+r43HeUM9jXFJx7A+yiTPfCooau/iCcP1wQh4NFw= k8s.io/cli-runtime v0.34.0/go.mod h1:t/skRecS73Piv+J+FmWIQA2N2/rDjdYSQzEE67LUUs8=
k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo=
k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY=
k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk= k8s.io/component-base v0.34.0 h1:bS8Ua3zlJzapklsB1dZgjEJuJEeHjj8yTu1gxE2zQX8=
k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU= k8s.io/component-base v0.34.0/go.mod h1:RSCqUdvIjjrEm81epPcjQ/DS+49fADvGSCkIP3IC6vg=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
k8s.io/kubectl v0.33.0 h1:HiRb1yqibBSCqic4pRZP+viiOBAnIdwYDpzUFejs07g= k8s.io/kubectl v0.34.0 h1:NcXz4TPTaUwhiX4LU+6r6udrlm0NsVnSkP3R9t0dmxs=
k8s.io/kubectl v0.33.0/go.mod h1:gAlGBuS1Jq1fYZ9AjGWbI/5Vk3M/VW2DK4g10Fpyn/0= k8s.io/kubectl v0.34.0/go.mod h1:bmd0W5i+HuG7/p5sqicr0Li0rR2iIhXL0oUyLF3OjR4=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ= sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I=
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o= sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM=
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA= sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=
sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY= sigs.k8s.io/kustomize/kyaml v0.20.1/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 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= 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/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2024 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -58,7 +58,7 @@ import (
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
image_automationv1 "github.com/fluxcd/image-automation-controller/api/v1beta2" image_automationv1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/pkg/update" "github.com/fluxcd/image-automation-controller/internal/update"
) )
var ( var (

View File

@ -39,7 +39,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/reconcile"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
aclapi "github.com/fluxcd/pkg/apis/acl" aclapi "github.com/fluxcd/pkg/apis/acl"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1" eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
@ -134,7 +134,11 @@ func (r *ImageUpdateAutomationReconciler) SetupWithManager(ctx context.Context,
if err := mgr.GetFieldIndexer().IndexField(ctx, &imagev1.ImageUpdateAutomation{}, repoRefKey, func(obj client.Object) []string { if err := mgr.GetFieldIndexer().IndexField(ctx, &imagev1.ImageUpdateAutomation{}, repoRefKey, func(obj client.Object) []string {
updater := obj.(*imagev1.ImageUpdateAutomation) updater := obj.(*imagev1.ImageUpdateAutomation)
ref := updater.Spec.SourceRef ref := updater.Spec.SourceRef
return []string{ref.Name} ns := ref.Namespace
if ns == "" {
ns = obj.GetNamespace()
}
return []string{fmt.Sprintf("%s/%s", ns, ref.Name)}
}); err != nil { }); err != nil {
return err return err
} }
@ -148,7 +152,7 @@ func (r *ImageUpdateAutomationReconciler) SetupWithManager(ctx context.Context,
builder.WithPredicates(sourceConfigChangePredicate{}), builder.WithPredicates(sourceConfigChangePredicate{}),
). ).
Watches( Watches(
&imagev1_reflect.ImagePolicy{}, &reflectorv1.ImagePolicy{},
handler.EnqueueRequestsFromMapFunc(r.automationsForImagePolicy), handler.EnqueueRequestsFromMapFunc(r.automationsForImagePolicy),
builder.WithPredicates(latestImageChangePredicate{}), builder.WithPredicates(latestImageChangePredicate{}),
). ).
@ -162,8 +166,8 @@ func (r *ImageUpdateAutomationReconciler) SetupWithManager(ctx context.Context,
// particular source.GitRepository object. // particular source.GitRepository object.
func (r *ImageUpdateAutomationReconciler) automationsForGitRepo(ctx context.Context, obj client.Object) []reconcile.Request { func (r *ImageUpdateAutomationReconciler) automationsForGitRepo(ctx context.Context, obj client.Object) []reconcile.Request {
var autoList imagev1.ImageUpdateAutomationList var autoList imagev1.ImageUpdateAutomationList
if err := r.List(ctx, &autoList, client.InNamespace(obj.GetNamespace()), objKey := fmt.Sprintf("%s/%s", obj.GetNamespace(), obj.GetName())
client.MatchingFields{repoRefKey: obj.GetName()}); err != nil { if err := r.List(ctx, &autoList, client.MatchingFields{repoRefKey: objKey}); err != nil {
ctrl.LoggerFrom(ctx).Error(err, "failed to list ImageUpdateAutomations for GitRepository change") ctrl.LoggerFrom(ctx).Error(err, "failed to list ImageUpdateAutomations for GitRepository change")
return nil return nil
} }
@ -396,6 +400,10 @@ func (r *ImageUpdateAutomationReconciler) reconcile(ctx context.Context, sp *pat
if r.features[features.GitShallowClone] { if r.features[features.GitShallowClone] {
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone()) checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone())
} }
if r.features[features.GitSparseCheckout] && obj.Spec.Update.Path != "" {
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionSparseCheckoutDirectories(obj.Spec.Update.Path))
}
// If full sync is still not needed, configure last observed commit to // If full sync is still not needed, configure last observed commit to
// perform optimized clone and obtain a non-concrete commit if the remote // perform optimized clone and obtain a non-concrete commit if the remote
// has not changed. // has not changed.
@ -477,6 +485,14 @@ func (r *ImageUpdateAutomationReconciler) reconcile(ctx context.Context, sp *pat
pushResult, err = sm.CommitAndPush(ctx, obj, policyResult, pushCfg...) pushResult, err = sm.CommitAndPush(ctx, obj, policyResult, pushCfg...)
if err != nil { if err != nil {
// Check if error is due to removed template field usage.
// Set Stalled condition and return nil error to prevent requeue, allowing user to fix template.
if errors.Is(err, source.ErrRemovedTemplateField) {
conditions.MarkStalled(obj, imagev1.RemovedTemplateFieldReason, "%s", err)
result, retErr = ctrl.Result{}, nil
return
}
e := fmt.Errorf("failed to update source: %w", err) e := fmt.Errorf("failed to update source: %w", err)
conditions.MarkFalse(obj, meta.ReadyCondition, imagev1.GitOperationFailedReason, "%s", e) conditions.MarkFalse(obj, meta.ReadyCondition, imagev1.GitOperationFailedReason, "%s", e)
result, retErr = ctrl.Result{}, e result, retErr = ctrl.Result{}, e
@ -533,7 +549,7 @@ func (r *ImageUpdateAutomationReconciler) reconcileDelete(obj *imagev1.ImageUpda
// getPolicies returns list of policies in the given namespace that have latest // getPolicies returns list of policies in the given namespace that have latest
// image. // image.
func getPolicies(ctx context.Context, kclient client.Client, namespace string, selector *metav1.LabelSelector) ([]imagev1_reflect.ImagePolicy, error) { func getPolicies(ctx context.Context, kclient client.Client, namespace string, selector *metav1.LabelSelector) ([]reflectorv1.ImagePolicy, error) {
policySelector := labels.Everything() policySelector := labels.Everything()
var err error var err error
if selector != nil { if selector != nil {
@ -542,12 +558,12 @@ func getPolicies(ctx context.Context, kclient client.Client, namespace string, s
} }
} }
var policies imagev1_reflect.ImagePolicyList var policies reflectorv1.ImagePolicyList
if err := kclient.List(ctx, &policies, &client.ListOptions{Namespace: namespace, LabelSelector: policySelector}); err != nil { if err := kclient.List(ctx, &policies, &client.ListOptions{Namespace: namespace, LabelSelector: policySelector}); err != nil {
return nil, fmt.Errorf("failed to list policies: %w", err) return nil, fmt.Errorf("failed to list policies: %w", err)
} }
readyPolicies := []imagev1_reflect.ImagePolicy{} readyPolicies := []reflectorv1.ImagePolicy{}
for _, policy := range policies.Items { for _, policy := range policies.Items {
// Ignore the policies that don't have a latest image. // Ignore the policies that don't have a latest image.
if policy.Status.LatestRef == nil { if policy.Status.LatestRef == nil {

View File

@ -45,7 +45,7 @@ import (
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
aclapi "github.com/fluxcd/pkg/apis/acl" aclapi "github.com/fluxcd/pkg/apis/acl"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/gittestserver" "github.com/fluxcd/pkg/gittestserver"
@ -58,7 +58,6 @@ import (
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2" imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/internal/source" "github.com/fluxcd/image-automation-controller/internal/source"
"github.com/fluxcd/image-automation-controller/internal/testutil" "github.com/fluxcd/image-automation-controller/internal/testutil"
"github.com/fluxcd/image-automation-controller/pkg/test"
) )
const ( const (
@ -71,12 +70,12 @@ const (
Automation: {{ .AutomationObject }} Automation: {{ .AutomationObject }}
Files: Files:
{{ range $filename, $_ := .Updated.Files -}} {{ range $filename, $_ := .Changed.FileChanges -}}
- {{ $filename }} - {{ $filename }}
{{ end -}} {{ end -}}
Objects: Objects:
{{ range $resource, $_ := .Updated.Objects -}} {{ range $resource, $_ := .Changed.Objects -}}
{{ if eq $resource.Kind "Deployment" -}} {{ if eq $resource.Kind "Deployment" -}}
- {{ $resource.Kind | lower }} {{ $resource.Name | lower }} - {{ $resource.Kind | lower }} {{ $resource.Name | lower }}
{{ else -}} {{ else -}}
@ -85,8 +84,10 @@ Objects:
{{ end -}} {{ end -}}
Images: Images:
{{ range .Updated.Images -}} {{ range .Changed.Changes -}}
- {{.}} ({{.Policy.Name}}) {{ if .Setter -}}
- {{.NewValue}} ({{.Setter}})
{{ end -}}
{{ end -}} {{ end -}}
` `
testCommitMessageFmt = `Commit summary testCommitMessageFmt = `Commit summary
@ -98,7 +99,7 @@ Files:
Objects: Objects:
- deployment test - deployment test
Images: Images:
- helloworld:v1.0.0 (%s) - helloworld:v1.0.0 (%s:%s)
` `
) )
@ -139,12 +140,12 @@ func TestImageUpdateAutomationReconciler_deleteBeforeFinalizer(t *testing.T) {
func TestImageUpdateAutomationReconciler_watchSourceAndLatestImage(t *testing.T) { func TestImageUpdateAutomationReconciler_watchSourceAndLatestImage(t *testing.T) {
g := NewWithT(t) g := NewWithT(t)
policySpec := imagev1_reflect.ImagePolicySpec{ policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{ ImageRepositoryRef: meta.NamespacedObjectReference{
Name: "not-expected-to-exist", Name: "not-expected-to-exist",
}, },
Policy: imagev1_reflect.ImagePolicyChoice{ Policy: reflectorv1.ImagePolicyChoice{
SemVer: &imagev1_reflect.SemVerPolicy{ SemVer: &reflectorv1.SemVerPolicy{
Range: "1.x", Range: "1.x",
}, },
}, },
@ -265,12 +266,12 @@ func TestImageUpdateAutomationReconciler_suspended(t *testing.T) {
} }
func TestImageUpdateAutomationReconciler_Reconcile(t *testing.T) { func TestImageUpdateAutomationReconciler_Reconcile(t *testing.T) {
policySpec := imagev1_reflect.ImagePolicySpec{ policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{ ImageRepositoryRef: meta.NamespacedObjectReference{
Name: "not-expected-to-exist", Name: "not-expected-to-exist",
}, },
Policy: imagev1_reflect.ImagePolicyChoice{ Policy: reflectorv1.ImagePolicyChoice{
SemVer: &imagev1_reflect.SemVerPolicy{ SemVer: &reflectorv1.SemVerPolicy{
Range: "1.x", Range: "1.x",
}, },
}, },
@ -705,12 +706,12 @@ func TestImageUpdateAutomationReconciler_Reconcile(t *testing.T) {
} }
func TestImageUpdateAutomationReconciler_commitMessage(t *testing.T) { func TestImageUpdateAutomationReconciler_commitMessage(t *testing.T) {
policySpec := imagev1_reflect.ImagePolicySpec{ policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{ ImageRepositoryRef: meta.NamespacedObjectReference{
Name: "not-expected-to-exist", Name: "not-expected-to-exist",
}, },
Policy: imagev1_reflect.ImagePolicyChoice{ Policy: reflectorv1.ImagePolicyChoice{
SemVer: &imagev1_reflect.SemVerPolicy{ SemVer: &reflectorv1.SemVerPolicy{
Range: "1.x", Range: "1.x",
}, },
}, },
@ -727,7 +728,7 @@ func TestImageUpdateAutomationReconciler_commitMessage(t *testing.T) {
name: "template with update Result", name: "template with update Result",
template: testCommitTemplate, template: testCommitTemplate,
wantCommitMsg: func(policyName, policyNS string) string { wantCommitMsg: func(policyName, policyNS string) string {
return fmt.Sprintf(testCommitMessageFmt, policyNS, policyName) return fmt.Sprintf(testCommitMessageFmt, policyNS, policyNS, policyName)
}, },
}, },
{ {
@ -841,14 +842,142 @@ Automation: %s/update-test
} }
} }
func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) { // TestImageUpdateAutomationReconciler_removedTemplateField tests removed template field usage (.Updated and .Changed.ImageResult).
g := NewWithT(t) func TestImageUpdateAutomationReconciler_removedTemplateField(t *testing.T) {
policySpec := imagev1_reflect.ImagePolicySpec{ policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{ ImageRepositoryRef: meta.NamespacedObjectReference{
Name: "not-expected-to-exist", Name: "not-expected-to-exist",
}, },
Policy: imagev1_reflect.ImagePolicyChoice{ Policy: reflectorv1.ImagePolicyChoice{
SemVer: &imagev1_reflect.SemVerPolicy{ SemVer: &reflectorv1.SemVerPolicy{
Range: "1.x",
},
},
}
fixture := "testdata/appconfig"
latest := "helloworld:v1.0.0"
testCases := []struct {
name string
template string
expectedErrMsg string
}{
{
name: ".Updated field",
template: `Commit summary
Automation: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Updated.Files -}}
- {{ $filename }}
{{ end -}}
Objects:
{{ range $resource, $_ := .Updated.Objects -}}
{{ if eq $resource.Kind "Deployment" -}}
- {{ $resource.Kind | lower }} {{ $resource.Name | lower }}
{{ else -}}
- {{ $resource.Kind }} {{ $resource.Name }}
{{ end -}}
{{ end -}}
Images:
{{ range .Updated.Images -}}
- {{.}} ({{.Policy.Name}})
{{ end -}}
`,
expectedErrMsg: "template uses removed '.Updated' field",
},
{
name: ".Changed.ImageResult field",
template: `Commit summary
Automation: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Changed.ImageResult.Files -}}
- {{ $filename }}
{{ end -}}
Objects:
{{ range $resource, $_ := .Changed.ImageResult.Objects -}}
- {{ $resource.Kind }} {{ $resource.Name }}
{{ end -}}
Images:
{{ range .Changed.ImageResult.Images -}}
- {{.}} ({{.Policy.Name}})
{{ end -}}
`,
expectedErrMsg: "template uses removed '.Changed.ImageResult' field",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
ctx := context.TODO()
namespace, err := testEnv.CreateNamespace(ctx, "image-auto-test")
g.Expect(err).ToNot(HaveOccurred())
defer func() { g.Expect(testEnv.Delete(ctx, namespace)).To(Succeed()) }()
testWithRepoAndImagePolicy(
ctx, g, testEnv, namespace.Name, fixture, policySpec, latest,
func(g *WithT, s repoAndPolicyArgs, repoURL string, localRepo *extgogit.Repository) {
policyKey := types.NamespacedName{
Name: s.imagePolicyName,
Namespace: s.namespace,
}
_ = testutil.CommitInRepo(ctx, g, repoURL, s.branch, originRemote, "Install setter marker", func(tmp string) {
g.Expect(testutil.ReplaceMarker(filepath.Join(tmp, "deploy.yaml"), policyKey)).To(Succeed())
})
preChangeCommitId := testutil.CommitIdFromBranch(localRepo, s.branch)
waitForNewHead(g, localRepo, s.branch, preChangeCommitId)
preChangeCommitId = testutil.CommitIdFromBranch(localRepo, s.branch)
updateStrategy := &imagev1.UpdateStrategy{
Strategy: imagev1.UpdateStrategySetters,
}
err := createImageUpdateAutomation(ctx, testEnv, "update-test", s.namespace, s.gitRepoName, s.gitRepoNamespace, s.branch, s.branch, "", tc.template, "", updateStrategy)
g.Expect(err).ToNot(HaveOccurred())
defer func() {
g.Expect(deleteImageUpdateAutomation(ctx, testEnv, "update-test", s.namespace)).To(Succeed())
}()
imageUpdateKey := types.NamespacedName{
Namespace: s.namespace,
Name: "update-test",
}
g.Eventually(func() bool {
var imageUpdate imagev1.ImageUpdateAutomation
_ = testEnv.Get(context.TODO(), imageUpdateKey, &imageUpdate)
stalledCondition := apimeta.FindStatusCondition(imageUpdate.Status.Conditions, meta.StalledCondition)
return stalledCondition != nil &&
stalledCondition.Status == metav1.ConditionTrue &&
stalledCondition.Reason == imagev1.RemovedTemplateFieldReason &&
strings.Contains(stalledCondition.Message, tc.expectedErrMsg)
}, timeout).Should(BeTrue())
head, _ := localRepo.Head()
g.Expect(head.Hash().String()).To(Equal(preChangeCommitId))
},
)
})
}
}
func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
g := NewWithT(t)
policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{
Name: "not-expected-to-exist",
},
Policy: reflectorv1.ImagePolicyChoice{
SemVer: &reflectorv1.SemVerPolicy{
Range: "1.x", Range: "1.x",
}, },
}, },
@ -875,7 +1004,7 @@ func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
testWithCustomRepoAndImagePolicy( testWithCustomRepoAndImagePolicy(
ctx, g, testEnv, fixture, policySpec, latest, args, ctx, g, testEnv, fixture, policySpec, latest, args,
func(g *WithT, s repoAndPolicyArgs, repoURL string, localRepo *extgogit.Repository) { func(g *WithT, s repoAndPolicyArgs, repoURL string, localRepo *extgogit.Repository) {
commitMessage := fmt.Sprintf(testCommitMessageFmt, s.namespace, s.imagePolicyName) commitMessage := fmt.Sprintf(testCommitMessageFmt, s.namespace, s.namespace, s.imagePolicyName)
// Update the setter marker in the repo. // Update the setter marker in the repo.
policyKey := types.NamespacedName{ policyKey := types.NamespacedName{
@ -926,7 +1055,7 @@ func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
r := &ImageUpdateAutomationReconciler{ r := &ImageUpdateAutomationReconciler{
Client: fakeclient.NewClientBuilder(). Client: fakeclient.NewClientBuilder().
WithScheme(testEnv.Scheme()). WithScheme(testEnv.Scheme()).
WithStatusSubresource(&imagev1.ImageUpdateAutomation{}, &imagev1_reflect.ImagePolicy{}). WithStatusSubresource(&imagev1.ImageUpdateAutomation{}, &reflectorv1.ImagePolicy{}).
Build(), Build(),
EventRecorder: testEnv.GetEventRecorderFor("image-automation-controller"), EventRecorder: testEnv.GetEventRecorderFor("image-automation-controller"),
NoCrossNamespaceRef: true, NoCrossNamespaceRef: true,
@ -975,12 +1104,12 @@ func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
} }
func TestImageUpdateAutomationReconciler_updatePath(t *testing.T) { func TestImageUpdateAutomationReconciler_updatePath(t *testing.T) {
policySpec := imagev1_reflect.ImagePolicySpec{ policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{ ImageRepositoryRef: meta.NamespacedObjectReference{
Name: "not-expected-to-exist", Name: "not-expected-to-exist",
}, },
Policy: imagev1_reflect.ImagePolicyChoice{ Policy: reflectorv1.ImagePolicyChoice{
SemVer: &imagev1_reflect.SemVerPolicy{ SemVer: &reflectorv1.SemVerPolicy{
Range: "1.x", Range: "1.x",
}, },
}, },
@ -1057,12 +1186,12 @@ func TestImageUpdateAutomationReconciler_updatePath(t *testing.T) {
} }
func TestImageUpdateAutomationReconciler_signedCommit(t *testing.T) { func TestImageUpdateAutomationReconciler_signedCommit(t *testing.T) {
policySpec := imagev1_reflect.ImagePolicySpec{ policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{ ImageRepositoryRef: meta.NamespacedObjectReference{
Name: "not-expected-to-exist", Name: "not-expected-to-exist",
}, },
Policy: imagev1_reflect.ImagePolicyChoice{ Policy: reflectorv1.ImagePolicyChoice{
SemVer: &imagev1_reflect.SemVerPolicy{ SemVer: &reflectorv1.SemVerPolicy{
Range: "1.x", Range: "1.x",
}, },
}, },
@ -1279,7 +1408,7 @@ func TestImageUpdateAutomationReconciler_e2e(t *testing.T) {
} }
} }
func TestImageUpdateAutomationReconciler_defaulting(t *testing.T) { func TestImageUpdateAutomationReconciler_DefaultUpdate(t *testing.T) {
g := NewWithT(t) g := NewWithT(t)
branch := rand.String(8) branch := rand.String(8)
@ -1338,6 +1467,70 @@ func TestImageUpdateAutomationReconciler_defaulting(t *testing.T) {
To(Equal(&imagev1.UpdateStrategy{Strategy: imagev1.UpdateStrategySetters})) To(Equal(&imagev1.UpdateStrategy{Strategy: imagev1.UpdateStrategySetters}))
} }
func TestImageUpdateAutomationReconciler_DefaultStrategy(t *testing.T) {
g := NewWithT(t)
branch := rand.String(8)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// Create a test namespace.
namespace, err := testEnv.CreateNamespace(ctx, "image-auto-test")
g.Expect(err).ToNot(HaveOccurred())
defer func() { g.Expect(testEnv.Delete(ctx, namespace)).To(Succeed()) }()
// Create an instance of ImageUpdateAutomation.
key := types.NamespacedName{
Name: "update-" + rand.String(5),
Namespace: namespace.Name,
}
auto := &imagev1.ImageUpdateAutomation{
ObjectMeta: metav1.ObjectMeta{
Name: key.Name,
Namespace: key.Namespace,
},
Spec: imagev1.ImageUpdateAutomationSpec{
SourceRef: imagev1.CrossNamespaceSourceReference{
Kind: "GitRepository",
Name: "garbage",
},
Interval: metav1.Duration{Duration: 2 * time.Hour},
GitSpec: &imagev1.GitSpec{
Checkout: &imagev1.GitCheckoutSpec{
Reference: sourcev1.GitRepositoryRef{
Branch: branch,
},
},
Commit: imagev1.CommitSpec{
Author: imagev1.CommitUser{
Email: testAuthorEmail,
},
MessageTemplate: "nothing",
},
},
Update: &imagev1.UpdateStrategy{
Path: "./test-path",
},
},
}
g.Expect(testEnv.Create(ctx, auto)).To(Succeed())
defer func() {
g.Expect(testEnv.Delete(ctx, auto)).To(Succeed())
}()
// Should default .spec.update to {strategy: Setters}.
var fetchedAuto imagev1.ImageUpdateAutomation
g.Eventually(func() bool {
err := testEnv.Get(ctx, key, &fetchedAuto)
return err == nil
}, timeout, time.Second).Should(BeTrue())
g.Expect(fetchedAuto.Spec.Update).
To(Equal(&imagev1.UpdateStrategy{
Strategy: imagev1.UpdateStrategySetters,
Path: "./test-path",
}))
}
func TestImageUpdateAutomationReconciler_notify(t *testing.T) { func TestImageUpdateAutomationReconciler_notify(t *testing.T) {
g := NewWithT(t) g := NewWithT(t)
testPushResult, err := source.NewPushResult("branch", "rev", "test commit message") testPushResult, err := source.NewPushResult("branch", "rev", "test commit message")
@ -1528,10 +1721,10 @@ func Test_getPolicies(t *testing.T) {
// Create all the test policies. // Create all the test policies.
testObjects := []client.Object{} testObjects := []client.Object{}
for _, p := range tt.policies { for _, p := range tt.policies {
aPolicy := &imagev1_reflect.ImagePolicy{} aPolicy := &reflectorv1.ImagePolicy{}
aPolicy.Name = p.name aPolicy.Name = p.name
aPolicy.Namespace = p.namespace aPolicy.Namespace = p.namespace
aPolicy.Status = imagev1_reflect.ImagePolicyStatus{ aPolicy.Status = reflectorv1.ImagePolicyStatus{
LatestRef: testutil.ImageToRef(p.latestImage), LatestRef: testutil.ImageToRef(p.latestImage),
} }
aPolicy.Labels = p.labels aPolicy.Labels = p.labels
@ -1652,7 +1845,7 @@ func compareRepoWithExpected(ctx context.Context, g *WithT, repoURL, branch, fix
defer wt.Filesystem.Remove(".") defer wt.Filesystem.Remove(".")
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
test.ExpectMatchingDirectories(g, wt.Filesystem.Root(), expected) testutil.ExpectMatchingDirectories(g, wt.Filesystem.Root(), expected)
} }
func waitForNewHead(g *WithT, repo *extgogit.Repository, branch, preChangeHash string) { func waitForNewHead(g *WithT, repo *extgogit.Repository, branch, preChangeHash string) {
@ -1744,7 +1937,7 @@ func testWithRepoAndImagePolicy(
kClient client.Client, kClient client.Client,
namespace string, namespace string,
fixture string, fixture string,
policySpec imagev1_reflect.ImagePolicySpec, policySpec reflectorv1.ImagePolicySpec,
latest string, latest string,
testFunc testWithRepoAndImagePolicyTestFunc) { testFunc testWithRepoAndImagePolicyTestFunc) {
// Generate unique repo and policy arguments. // Generate unique repo and policy arguments.
@ -1761,7 +1954,7 @@ func testWithCustomRepoAndImagePolicy(
g *WithT, g *WithT,
kClient client.Client, kClient client.Client,
fixture string, fixture string,
policySpec imagev1_reflect.ImagePolicySpec, policySpec reflectorv1.ImagePolicySpec,
latest string, latest string,
args repoAndPolicyArgs, args repoAndPolicyArgs,
testFunc testWithRepoAndImagePolicyTestFunc) { testFunc testWithRepoAndImagePolicyTestFunc) {
@ -1819,12 +2012,12 @@ func createGitRepository(ctx context.Context, kClient client.Client, name, names
} }
func createImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, repoRef, semverRange, latest string) error { func createImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, repoRef, semverRange, latest string) error {
policySpec := imagev1_reflect.ImagePolicySpec{ policySpec := reflectorv1.ImagePolicySpec{
ImageRepositoryRef: meta.NamespacedObjectReference{ ImageRepositoryRef: meta.NamespacedObjectReference{
Name: repoRef, Name: repoRef,
}, },
Policy: imagev1_reflect.ImagePolicyChoice{ Policy: reflectorv1.ImagePolicyChoice{
SemVer: &imagev1_reflect.SemVerPolicy{ SemVer: &reflectorv1.SemVerPolicy{
Range: semverRange, Range: semverRange,
}, },
}, },
@ -1832,8 +2025,8 @@ func createImagePolicyWithLatestImage(ctx context.Context, kClient client.Client
return createImagePolicyWithLatestImageForSpec(ctx, kClient, name, namespace, policySpec, latest) return createImagePolicyWithLatestImageForSpec(ctx, kClient, name, namespace, policySpec, latest)
} }
func createImagePolicyWithLatestImageForSpec(ctx context.Context, kClient client.Client, name, namespace string, policySpec imagev1_reflect.ImagePolicySpec, latest string) error { func createImagePolicyWithLatestImageForSpec(ctx context.Context, kClient client.Client, name, namespace string, policySpec reflectorv1.ImagePolicySpec, latest string) error {
policy := &imagev1_reflect.ImagePolicy{ policy := &reflectorv1.ImagePolicy{
Spec: policySpec, Spec: policySpec,
} }
policy.Name = name policy.Name = name
@ -1848,7 +2041,7 @@ func createImagePolicyWithLatestImageForSpec(ctx context.Context, kClient client
} }
func updateImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, latest string) error { func updateImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, latest string) error {
policy := &imagev1_reflect.ImagePolicy{} policy := &reflectorv1.ImagePolicy{}
key := types.NamespacedName{ key := types.NamespacedName{
Name: name, Name: name,
Namespace: namespace, Namespace: namespace,
@ -1913,7 +2106,7 @@ func deleteImageUpdateAutomation(ctx context.Context, kClient client.Client, nam
} }
func deleteImagePolicy(ctx context.Context, kClient client.Client, name, namespace string) error { func deleteImagePolicy(ctx context.Context, kClient client.Client, name, namespace string) error {
imagePolicy := &imagev1_reflect.ImagePolicy{} imagePolicy := &reflectorv1.ImagePolicy{}
imagePolicy.Name = name imagePolicy.Name = name
imagePolicy.Namespace = namespace imagePolicy.Namespace = namespace
return kClient.Delete(ctx, imagePolicy) return kClient.Delete(ctx, imagePolicy)

View File

@ -20,7 +20,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/predicate"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
) )
// latestImageChangePredicate implements a predicate for latest image change. // latestImageChangePredicate implements a predicate for latest image change.
@ -43,12 +43,12 @@ func (latestImageChangePredicate) Update(e event.UpdateEvent) bool {
return false return false
} }
oldSource, ok := e.ObjectOld.(*imagev1_reflect.ImagePolicy) oldSource, ok := e.ObjectOld.(*reflectorv1.ImagePolicy)
if !ok { if !ok {
return false return false
} }
newSource, ok := e.ObjectNew.(*imagev1_reflect.ImagePolicy) newSource, ok := e.ObjectNew.(*reflectorv1.ImagePolicy)
if !ok { if !ok {
return false return false
} }

View File

@ -22,19 +22,19 @@ import (
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/event"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
) )
func Test_latestImageChangePredicate_Update(t *testing.T) { func Test_latestImageChangePredicate_Update(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
beforeFunc func(oldObj, newObj *imagev1_reflect.ImagePolicy) beforeFunc func(oldObj, newObj *reflectorv1.ImagePolicy)
want bool want bool
}{ }{
{ {
name: "no latest image", name: "no latest image",
beforeFunc: func(oldObj, newObj *imagev1_reflect.ImagePolicy) { beforeFunc: func(oldObj, newObj *reflectorv1.ImagePolicy) {
oldObj.Status.LatestRef = nil oldObj.Status.LatestRef = nil
newObj.Status.LatestRef = nil newObj.Status.LatestRef = nil
}, },
@ -42,17 +42,17 @@ func Test_latestImageChangePredicate_Update(t *testing.T) {
}, },
{ {
name: "new image, no old image", name: "new image, no old image",
beforeFunc: func(oldObj, newObj *imagev1_reflect.ImagePolicy) { beforeFunc: func(oldObj, newObj *reflectorv1.ImagePolicy) {
oldObj.Status.LatestRef = nil oldObj.Status.LatestRef = nil
newObj.Status.LatestRef = &imagev1_reflect.ImageRef{Name: "foo"} newObj.Status.LatestRef = &reflectorv1.ImageRef{Name: "foo"}
}, },
want: true, want: true,
}, },
{ {
name: "different old and new image", name: "different old and new image",
beforeFunc: func(oldObj, newObj *imagev1_reflect.ImagePolicy) { beforeFunc: func(oldObj, newObj *reflectorv1.ImagePolicy) {
oldObj.Status.LatestRef = &imagev1_reflect.ImageRef{Name: "bar"} oldObj.Status.LatestRef = &reflectorv1.ImageRef{Name: "bar"}
newObj.Status.LatestRef = &imagev1_reflect.ImageRef{Name: "foo"} newObj.Status.LatestRef = &reflectorv1.ImageRef{Name: "foo"}
}, },
want: true, want: true,
}, },
@ -61,7 +61,7 @@ func Test_latestImageChangePredicate_Update(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t) g := NewWithT(t)
oldObj := &imagev1_reflect.ImagePolicy{} oldObj := &reflectorv1.ImagePolicy{}
newObj := oldObj.DeepCopy() newObj := oldObj.DeepCopy()
if tt.beforeFunc != nil { if tt.beforeFunc != nil {
tt.beforeFunc(oldObj, newObj) tt.beforeFunc(oldObj, newObj)

View File

@ -30,7 +30,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime" ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
"github.com/fluxcd/pkg/runtime/controller" "github.com/fluxcd/pkg/runtime/controller"
"github.com/fluxcd/pkg/runtime/testenv" "github.com/fluxcd/pkg/runtime/testenv"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
@ -56,7 +56,7 @@ func init() {
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
utilruntime.Must(imagev1_reflect.AddToScheme(scheme.Scheme)) utilruntime.Must(reflectorv1.AddToScheme(scheme.Scheme))
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme)) utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
utilruntime.Must(imagev1.AddToScheme(scheme.Scheme)) utilruntime.Must(imagev1.AddToScheme(scheme.Scheme))

View File

@ -34,6 +34,9 @@ const (
// GitAllBranchReferences enables the download of all branch head references // GitAllBranchReferences enables the download of all branch head references
// when push branches are configured. When enabled fixes fluxcd/flux2#3384. // when push branches are configured. When enabled fixes fluxcd/flux2#3384.
GitAllBranchReferences = "GitAllBranchReferences" GitAllBranchReferences = "GitAllBranchReferences"
// GitSparseCheckout enables the use of sparse checkout when pulling source from
// Git repositories.
GitSparseCheckout = "GitSparseCheckout"
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should // CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
// be cached. // be cached.
// //
@ -55,6 +58,10 @@ var features = map[string]bool{
// opt-out from v0.28 // opt-out from v0.28
GitAllBranchReferences: true, GitAllBranchReferences: true,
// GitSparseCheckout
// opt-in from v0.42
GitSparseCheckout: false,
// CacheSecretsAndConfigMaps // CacheSecretsAndConfigMaps
// opt-in from v0.29 // opt-in from v0.29
CacheSecretsAndConfigMaps: false, CacheSecretsAndConfigMaps: false,

View File

@ -25,10 +25,10 @@ import (
"github.com/fluxcd/pkg/runtime/logger" "github.com/fluxcd/pkg/runtime/logger"
"sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2" imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/pkg/update" "github.com/fluxcd/image-automation-controller/internal/update"
) )
var ( var (
@ -42,8 +42,8 @@ var (
// ApplyPolicies applies the given set of policies on the source present in the // ApplyPolicies applies the given set of policies on the source present in the
// workDir based on the provided ImageUpdateAutomation configuration. // workDir based on the provided ImageUpdateAutomation configuration.
func ApplyPolicies(ctx context.Context, workDir string, obj *imagev1.ImageUpdateAutomation, policies []imagev1_reflect.ImagePolicy) (update.ResultV2, error) { func ApplyPolicies(ctx context.Context, workDir string, obj *imagev1.ImageUpdateAutomation, policies []reflectorv1.ImagePolicy) (update.Result, error) {
var result update.ResultV2 var result update.Result
if obj.Spec.Update == nil { if obj.Spec.Update == nil {
return result, ErrNoUpdateStrategy return result, ErrNoUpdateStrategy
} }
@ -62,5 +62,5 @@ func ApplyPolicies(ctx context.Context, workDir string, obj *imagev1.ImageUpdate
} }
tracelog := log.FromContext(ctx).V(logger.TraceLevel) tracelog := log.FromContext(ctx).V(logger.TraceLevel)
return update.UpdateV2WithSetters(tracelog, manifestPath, manifestPath, policies) return update.UpdateWithSetters(tracelog, manifestPath, manifestPath, policies)
} }

View File

@ -26,12 +26,10 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2" imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/internal/testutil" "github.com/fluxcd/image-automation-controller/internal/testutil"
"github.com/fluxcd/image-automation-controller/pkg/test"
"github.com/fluxcd/image-automation-controller/pkg/update"
) )
func testdataPath(path string) string { func testdataPath(path string) string {
@ -48,7 +46,6 @@ func Test_applyPolicies(t *testing.T) {
inputPath string inputPath string
expectedPath string expectedPath string
wantErr bool wantErr bool
wantResult update.Result
}{ }{
{ {
name: "valid update strategy and one policy", name: "valid update strategy and one policy",
@ -118,12 +115,12 @@ func Test_applyPolicies(t *testing.T) {
workDir := t.TempDir() workDir := t.TempDir()
// Create all the policy objects. // Create all the policy objects.
policyList := []imagev1_reflect.ImagePolicy{} policyList := []reflectorv1.ImagePolicy{}
for name, image := range tt.policyLatestImages { for name, image := range tt.policyLatestImages {
policy := &imagev1_reflect.ImagePolicy{} policy := &reflectorv1.ImagePolicy{}
policy.Name = name policy.Name = name
policy.Namespace = testNS policy.Namespace = testNS
policy.Status = imagev1_reflect.ImagePolicyStatus{ policy.Status = reflectorv1.ImagePolicyStatus{
LatestRef: testutil.ImageToRef(image), LatestRef: testutil.ImageToRef(image),
} }
policyList = append(policyList, *policy) policyList = append(policyList, *policy)
@ -150,7 +147,7 @@ func Test_applyPolicies(t *testing.T) {
} }
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
imagev1_reflect.AddToScheme(scheme) reflectorv1.AddToScheme(scheme)
imagev1.AddToScheme(scheme) imagev1.AddToScheme(scheme)
_, err := ApplyPolicies(context.TODO(), workDir, updateAuto, policyList) _, err := ApplyPolicies(context.TODO(), workDir, updateAuto, policyList)
@ -166,7 +163,7 @@ func Test_applyPolicies(t *testing.T) {
} else { } else {
g.Expect(testutil.ReplaceMarker(filepath.Join(expected, "deploy.yaml"), targetPolicyKey)).ToNot(HaveOccurred()) g.Expect(testutil.ReplaceMarker(filepath.Join(expected, "deploy.yaml"), targetPolicyKey)).ToNot(HaveOccurred())
} }
test.ExpectMatchingDirectories(g, workDir, expected) testutil.ExpectMatchingDirectories(g, workDir, expected)
} }
}) })
} }

View File

@ -25,6 +25,7 @@ import (
"time" "time"
"github.com/ProtonMail/go-crypto/openpgp" "github.com/ProtonMail/go-crypto/openpgp"
"github.com/fluxcd/pkg/runtime/secrets"
"github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -62,13 +63,14 @@ type gitSrcCfg struct {
} }
func buildGitConfig(ctx context.Context, c client.Client, originKey, srcKey types.NamespacedName, gitSpec *imagev1.GitSpec, opts SourceOptions) (*gitSrcCfg, error) { func buildGitConfig(ctx context.Context, c client.Client, originKey, srcKey types.NamespacedName, gitSpec *imagev1.GitSpec, opts SourceOptions) (*gitSrcCfg, error) {
var err error
cfg := &gitSrcCfg{ cfg := &gitSrcCfg{
srcKey: srcKey, srcKey: srcKey,
} }
// Get the repo. // Get the repo.
repo := &sourcev1.GitRepository{} repo := &sourcev1.GitRepository{}
if err := c.Get(ctx, srcKey, repo); err != nil { if err = c.Get(ctx, srcKey, repo); err != nil {
if client.IgnoreNotFound(err) == nil { if client.IgnoreNotFound(err) == nil {
return nil, fmt.Errorf("referenced git repository does not exist: %w", err) return nil, fmt.Errorf("referenced git repository does not exist: %w", err)
} }
@ -94,14 +96,26 @@ func buildGitConfig(ctx context.Context, c client.Client, originKey, srcKey type
// Configure push first as the client options below depend on the push // Configure push first as the client options below depend on the push
// configuration. // configuration.
if err := configurePush(cfg, gitSpec, cfg.checkoutRef); err != nil { if err = configurePush(cfg, gitSpec, cfg.checkoutRef); err != nil {
return nil, err return nil, err
} }
proxyOpts, proxyURL, err := getProxyOpts(ctx, c, repo) var proxyURL *url.URL
var proxyOpts *transport.ProxyOptions
// Check if a proxy secret reference is provided in the GitRepository spec.
if repo.Spec.ProxySecretRef != nil {
secretRef := types.NamespacedName{
Name: repo.Spec.ProxySecretRef.Name,
Namespace: repo.GetNamespace(),
}
// Get the proxy URL from runtime/secret
proxyURL, err = secrets.ProxyURLFromSecretRef(ctx, c, secretRef)
if err != nil { if err != nil {
return nil, err return nil, err
} }
proxyOpts = &transport.ProxyOptions{URL: proxyURL.String()}
}
cfg.authOpts, err = getAuthOpts(ctx, c, repo, opts, proxyURL) cfg.authOpts, err = getAuthOpts(ctx, c, repo, opts, proxyURL)
if err != nil { if err != nil {
return nil, err return nil, err
@ -165,13 +179,15 @@ func configurePush(cfg *gitSrcCfg, gitSpec *imagev1.GitSpec, checkoutRef *source
func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitRepository, func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitRepository,
srcOpts SourceOptions, proxyURL *url.URL) (*git.AuthOptions, error) { srcOpts SourceOptions, proxyURL *url.URL) (*git.AuthOptions, error) {
var secret *corev1.Secret
var data map[string][]byte var data map[string][]byte
var err error var err error
if repo.Spec.SecretRef != nil { if repo.Spec.SecretRef != nil {
data, err = getSecretData(ctx, c, repo.Spec.SecretRef.Name, repo.GetNamespace()) secret, err = getSecret(ctx, c, repo.Spec.SecretRef.Name, repo.GetNamespace())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get auth secret '%s/%s': %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, err) return nil, fmt.Errorf("failed to get auth secret '%s/%s': %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, err)
} }
data = secret.Data
} }
u, err := url.Parse(repo.Spec.URL) u, err := url.Parse(repo.Spec.URL)
@ -188,7 +204,10 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
switch provider := repo.GetProvider(); provider { switch provider := repo.GetProvider(); provider {
case sourcev1.GitProviderAzure: // If AWS or GCP are added in the future they can be added here separated by a comma. case sourcev1.GitProviderAzure: // If AWS or GCP are added in the future they can be added here separated by a comma.
getCreds = func() (*authutils.GitCredentials, error) { getCreds = func() (*authutils.GitCredentials, error) {
var opts []auth.Option opts := []auth.Option{
auth.WithClient(c),
auth.WithServiceAccountNamespace(srcOpts.objNamespace),
}
if srcOpts.tokenCache != nil { if srcOpts.tokenCache != nil {
involvedObject := cache.InvolvedObject{ involvedObject := cache.InvolvedObject{
@ -211,24 +230,33 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
if repo.Spec.SecretRef == nil { if repo.Spec.SecretRef == nil {
return nil, fmt.Errorf("secretRef with github app data must be specified when provider is set to github: %w", ErrInvalidSourceConfiguration) return nil, fmt.Errorf("secretRef with github app data must be specified when provider is set to github: %w", ErrInvalidSourceConfiguration)
} }
authMethods, err := secrets.AuthMethodsFromSecret(ctx, secret, secrets.WithTLSSystemCertPool())
getCreds = func() (*authutils.GitCredentials, error) { if err != nil {
var opts []github.OptFunc return nil, err
}
if len(data) > 0 { if !authMethods.HasGitHubAppData() {
opts = append(opts, github.WithAppData(data)) return nil, fmt.Errorf("secretRef with github app data must be specified when provider is set to github: %w", ErrInvalidSourceConfiguration)
} }
getCreds = func() (*authutils.GitCredentials, error) {
var appOpts []github.OptFunc
appOpts = append(appOpts, github.WithAppData(authMethods.GitHubAppData))
if proxyURL != nil { if proxyURL != nil {
opts = append(opts, github.WithProxyURL(proxyURL)) appOpts = append(appOpts, github.WithProxyURL(proxyURL))
} }
if srcOpts.tokenCache != nil { if srcOpts.tokenCache != nil {
opts = append(opts, github.WithCache(srcOpts.tokenCache, imagev1.ImageUpdateAutomationKind, appOpts = append(appOpts, github.WithCache(srcOpts.tokenCache, imagev1.ImageUpdateAutomationKind,
srcOpts.objName, srcOpts.objNamespace, cache.OperationReconcile)) srcOpts.objName, srcOpts.objNamespace, cache.OperationReconcile))
} }
username, password, err := github.GetCredentials(ctx, opts...) if authMethods.HasTLS() {
appOpts = append(appOpts, github.WithTLSConfig(authMethods.TLS))
}
username, password, err := github.GetCredentials(ctx, appOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -239,7 +267,7 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
} }
default: default:
// analyze secret, if it has github app data, perhaps provider should have been github. // analyze secret, if it has github app data, perhaps provider should have been github.
if appID := data[github.AppIDKey]; len(appID) != 0 { if appID := data[github.KeyAppID]; len(appID) != 0 {
return nil, fmt.Errorf("secretRef '%s/%s' has github app data but provider is not set to github: %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, ErrInvalidSourceConfiguration) return nil, fmt.Errorf("secretRef '%s/%s' has github app data but provider is not set to github: %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, ErrInvalidSourceConfiguration)
} }
} }
@ -255,45 +283,6 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
return opts, nil return opts, nil
} }
func getProxyOpts(ctx context.Context, c client.Client, repo *sourcev1.GitRepository) (*transport.ProxyOptions, *url.URL, error) {
if repo.Spec.ProxySecretRef == nil {
return nil, nil, nil
}
name := repo.Spec.ProxySecretRef.Name
namespace := repo.GetNamespace()
proxyData, err := getSecretData(ctx, c, name, namespace)
if err != nil {
return nil, nil, fmt.Errorf("failed to get proxy secret '%s/%s': %w", namespace, name, err)
}
b, ok := proxyData["address"]
if !ok {
return nil, nil, fmt.Errorf("invalid proxy secret '%s/%s': key 'address' is missing", namespace, name)
}
address := string(b)
username := string(proxyData["username"])
password := string(proxyData["password"])
proxyOpts := &transport.ProxyOptions{
URL: address,
Username: username,
Password: password,
}
proxyURL, err := url.Parse(string(address))
if err != nil {
return nil, nil, fmt.Errorf("invalid address in proxy secret '%s/%s': %w", namespace, name, err)
}
switch {
case username != "" && password == "":
proxyURL.User = url.User(username)
case username != "" && password != "":
proxyURL.User = url.UserPassword(username, password)
}
return proxyOpts, proxyURL, nil
}
func getSigningEntity(ctx context.Context, c client.Client, namespace string, gitSpec *imagev1.GitSpec) (*openpgp.Entity, error) { func getSigningEntity(ctx context.Context, c client.Client, namespace string, gitSpec *imagev1.GitSpec) (*openpgp.Entity, error) {
secretName := gitSpec.Commit.SigningKey.SecretRef.Name secretName := gitSpec.Commit.SigningKey.SecretRef.Name
secretData, err := getSecretData(ctx, c, secretName, namespace) secretData, err := getSecretData(ctx, c, secretName, namespace)
@ -330,13 +319,21 @@ func getSigningEntity(ctx context.Context, c client.Client, namespace string, gi
} }
func getSecretData(ctx context.Context, c client.Client, name, namespace string) (map[string][]byte, error) { func getSecretData(ctx context.Context, c client.Client, name, namespace string) (map[string][]byte, error) {
key := types.NamespacedName{ secret, err := getSecret(ctx, c, name, namespace)
Namespace: namespace, if err != nil {
Name: name,
}
var secret corev1.Secret
if err := c.Get(ctx, key, &secret); err != nil {
return nil, err return nil, err
} }
return secret.Data, nil return secret.Data, nil
} }
func getSecret(ctx context.Context, c client.Client, name, namespace string) (*corev1.Secret, error) {
key := types.NamespacedName{
Namespace: namespace,
Name: name,
}
secret := &corev1.Secret{}
if err := c.Get(ctx, key, secret); err != nil {
return nil, err
}
return secret, nil
}

View File

@ -19,11 +19,9 @@ package source
import ( import (
"context" "context"
"fmt" "fmt"
"net/url"
"testing" "testing"
"time" "time"
"github.com/go-git/go-git/v5/plumbing/transport"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -32,12 +30,13 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/internal/testutil"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/github" "github.com/fluxcd/pkg/git/github"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/internal/testutil"
) )
func Test_getAuthOpts(t *testing.T) { func Test_getAuthOpts(t *testing.T) {
@ -183,9 +182,9 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
Name: "githubAppSecret", Name: "githubAppSecret",
}, },
Data: map[string][]byte{ Data: map[string][]byte{
github.AppIDKey: []byte("123"), github.KeyAppID: []byte("123"),
github.AppInstallationIDKey: []byte("456"), github.KeyAppInstallationID: []byte("456"),
github.AppPrivateKey: []byte("abc"), github.KeyAppPrivateKey: []byte("abc"),
}, },
}, },
beforeFunc: func(obj *sourcev1.GitRepository) { beforeFunc: func(obj *sourcev1.GitRepository) {
@ -196,6 +195,26 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
}, },
wantErr: "Key must be a PEM encoded PKCS1 or PKCS8 key", wantErr: "Key must be a PEM encoded PKCS1 or PKCS8 key",
}, },
{
name: "github provider with basic auth in secret",
url: "https://example.com/org/repo",
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "basic-auth-secret",
},
Data: map[string][]byte{
"username": []byte("abc"),
"password": []byte(""),
},
},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Provider = sourcev1.GitProviderGitHub
obj.Spec.SecretRef = &meta.LocalObjectReference{
Name: "basic-auth-secret",
}
},
wantErr: "secretRef with github app data must be specified when provider is set to github",
},
{ {
name: "generic provider with github app data in secret", name: "generic provider with github app data in secret",
url: "https://example.com/org/repo", url: "https://example.com/org/repo",
@ -204,7 +223,7 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
Name: "githubAppSecret", Name: "githubAppSecret",
}, },
Data: map[string][]byte{ Data: map[string][]byte{
github.AppIDKey: []byte("123"), github.KeyAppID: []byte("123"),
}, },
}, },
beforeFunc: func(obj *sourcev1.GitRepository) { beforeFunc: func(obj *sourcev1.GitRepository) {
@ -266,94 +285,6 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
} }
} }
func Test_getProxyOpts(t *testing.T) {
namespace := "default"
invalidProxy := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "invalid-proxy",
Namespace: namespace,
},
Data: map[string][]byte{
"url": []byte("https://example.com"),
},
}
validProxy := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "valid-proxy",
Namespace: namespace,
},
Data: map[string][]byte{
"address": []byte("https://example.com"),
"username": []byte("user"),
"password": []byte("pass"),
},
}
tests := []struct {
name string
secretName string
want *transport.ProxyOptions
wantProxyURL *url.URL
wantErr bool
}{
{
name: "non-existing secret",
secretName: "non-existing",
want: nil,
wantProxyURL: nil,
wantErr: true,
},
{
name: "invalid proxy secret",
secretName: "invalid-proxy",
want: nil,
wantProxyURL: nil,
wantErr: true,
},
{
name: "valid proxy secret",
secretName: "valid-proxy",
want: &transport.ProxyOptions{
URL: "https://example.com",
Username: "user",
Password: "pass",
},
wantProxyURL: &url.URL{
Scheme: "https",
Host: "example.com",
User: url.UserPassword("user", "pass"),
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
clientBuilder := fakeclient.NewClientBuilder().
WithScheme(scheme.Scheme).
WithObjects(invalidProxy, validProxy)
c := clientBuilder.Build()
gitRepo := &sourcev1.GitRepository{}
gitRepo.Namespace = namespace
if tt.secretName != "" {
gitRepo.Spec = sourcev1.GitRepositorySpec{
ProxySecretRef: &meta.LocalObjectReference{Name: tt.secretName},
}
}
got, gotProxyURL, err := getProxyOpts(context.TODO(), c, gitRepo)
if (err != nil) != tt.wantErr {
g.Fail(fmt.Sprintf("unexpected error: %v", err))
return
}
g.Expect(got).To(Equal(tt.want))
g.Expect(gotProxyURL).To(Equal(tt.wantProxyURL))
})
}
}
func Test_getSigningEntity(t *testing.T) { func Test_getSigningEntity(t *testing.T) {
g := NewWithT(t) g := NewWithT(t)

View File

@ -21,6 +21,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings" "strings"
"text/template" "text/template"
"time" "time"
@ -41,20 +42,42 @@ import (
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2" imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/pkg/update" "github.com/fluxcd/image-automation-controller/internal/update"
) )
// ErrInvalidSourceConfiguration is an error for invalid source configuration. // ErrInvalidSourceConfiguration is an error for invalid source configuration.
var ErrInvalidSourceConfiguration = errors.New("invalid source configuration") var ErrInvalidSourceConfiguration = errors.New("invalid source configuration")
// RemovedTemplateFieldError represents an error when a removed template field is used.
type RemovedTemplateFieldError struct {
Field string
}
func (e *RemovedTemplateFieldError) Error() string {
switch e.Field {
case ".Updated":
return "template uses removed '.Updated' field. Please use '.Changed' instead. See: https://fluxcd.io/flux/components/image/imageupdateautomations/#message-template"
case ".Changed.ImageResult":
return "template uses removed '.Changed.ImageResult' field. Please use '.Changed.FileChanges' or '.Changed.Objects' instead. See: https://fluxcd.io/flux/components/image/imageupdateautomations/#message-template"
default:
return fmt.Sprintf("template uses removed '%s' field. See: https://fluxcd.io/flux/components/image/imageupdateautomations/#message-template", e.Field)
}
}
func (e *RemovedTemplateFieldError) Is(target error) bool {
return errors.Is(target, ErrRemovedTemplateField)
}
// ErrRemovedTemplateField is a sentinel error for removed template field usage.
var ErrRemovedTemplateField = &RemovedTemplateFieldError{}
const defaultMessageTemplate = `Update from image update automation` const defaultMessageTemplate = `Update from image update automation`
// TemplateData is the type of the value given to the commit message // TemplateData is the type of the value given to the commit message
// template. // template.
type TemplateData struct { type TemplateData struct {
AutomationObject types.NamespacedName AutomationObject types.NamespacedName
Updated update.Result Changed update.Result
Changed update.ResultV2
Values map[string]string Values map[string]string
} }
@ -196,6 +219,19 @@ func WithCheckoutOptionShallowClone() CheckoutOption {
} }
} }
// WithCheckoutOptionSparseCheckoutDirectories is a CheckoutOption option to configure
// SparseCheckoutDirectories.
func WithCheckoutOptionSparseCheckoutDirectories(updatePath string) CheckoutOption {
return func(cc *repository.CloneConfig) {
cleanedPath := filepath.Clean(updatePath)
if cleanedPath == "." {
// Do not set SparseCheckoutDirectories if repository root is specified
return
}
cc.SparseCheckoutDirectories = []string{cleanedPath}
}
}
// CheckoutSource clones and checks out the source. If a push branch is // CheckoutSource clones and checks out the source. If a push branch is
// configured that doesn't match with the checkout branch, a checkout to the // configured that doesn't match with the checkout branch, a checkout to the
// push branch is also performed. This ensures any change and push operation // push branch is also performed. This ensures any change and push operation
@ -254,7 +290,7 @@ func WithPushConfigOptions(opts map[string]string) PushConfig {
// CommitAndPush performs a commit in the source and pushes it to the remote // CommitAndPush performs a commit in the source and pushes it to the remote
// repository. // repository.
func (sm SourceManager) CommitAndPush(ctx context.Context, obj *imagev1.ImageUpdateAutomation, policyResult update.ResultV2, pushOptions ...PushConfig) (*PushResult, error) { func (sm SourceManager) CommitAndPush(ctx context.Context, obj *imagev1.ImageUpdateAutomation, policyResult update.Result, pushOptions ...PushConfig) (*PushResult, error) {
tracelog := log.FromContext(ctx).V(logger.TraceLevel) tracelog := log.FromContext(ctx).V(logger.TraceLevel)
// Make sure there were file changes that need to be committed. // Make sure there were file changes that need to be committed.
@ -265,7 +301,6 @@ func (sm SourceManager) CommitAndPush(ctx context.Context, obj *imagev1.ImageUpd
// Perform a Git commit. // Perform a Git commit.
templateValues := &TemplateData{ templateValues := &TemplateData{
AutomationObject: sm.automationObjKey, AutomationObject: sm.automationObjKey,
Updated: policyResult.ImageResult,
Changed: policyResult, Changed: policyResult,
Values: obj.Spec.GitSpec.Commit.MessageTemplateValues, Values: obj.Spec.GitSpec.Commit.MessageTemplateValues,
} }
@ -342,11 +377,32 @@ func templateMsg(messageTemplate string, templateValues *TemplateData) (string,
b := &strings.Builder{} b := &strings.Builder{}
if err := t.Execute(b, *templateValues); err != nil { if err := t.Execute(b, *templateValues); err != nil {
if removedFieldErr := checkRemovedTemplateField(err); removedFieldErr != nil {
return "", removedFieldErr
}
return "", fmt.Errorf("failed to run template from spec: %w", err) return "", fmt.Errorf("failed to run template from spec: %w", err)
} }
return b.String(), nil return b.String(), nil
} }
// checkRemovedTemplateField checks if the template error is due to removed fields
func checkRemovedTemplateField(err error) error {
removedFieldChecks := []struct {
fieldName string
errorPattern string
}{
{".Updated", "can't evaluate field Updated in type source.TemplateData"},
{".Changed.ImageResult", "can't evaluate field ImageResult in type update.Result"},
}
for _, check := range removedFieldChecks {
if strings.Contains(err.Error(), check.errorPattern) {
return &RemovedTemplateFieldError{Field: check.fieldName}
}
}
return nil
}
// PushResultOption allows configuring the options of PushResult. // PushResultOption allows configuring the options of PushResult.
type PushResultOption func(*PushResult) type PushResultOption func(*PushResult)

View File

@ -42,7 +42,7 @@ import (
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/gittestserver" "github.com/fluxcd/pkg/gittestserver"
@ -56,7 +56,7 @@ import (
const ( const (
originRemote = "origin" originRemote = "origin"
testCommitTemplate = `Commit summary testCommitTemplateRemoved = `Commit summary
Automation: {{ .AutomationObject }} Automation: {{ .AutomationObject }}
@ -101,11 +101,30 @@ Automation: {{ .AutomationObject }}
Cluster: {{ index .Values "cluster" }} Cluster: {{ index .Values "cluster" }}
Testing: {{ .Values.testing }} Testing: {{ .Values.testing }}
`
testCommitTemplateImageResult = `Commit summary
Automation: {{ .AutomationObject }}
Files:
{{ range $filename, $_ := .Changed.ImageResult.Files -}}
- {{ $filename }}
{{ end -}}
Objects:
{{ range $resource, $_ := .Changed.ImageResult.Objects -}}
- {{ $resource.Kind }} {{ $resource.Name }}
{{ end -}}
Images:
{{ range .Changed.ImageResult.Images -}}
- {{.}} ({{.Policy.Name}})
{{ end -}}
` `
) )
func init() { func init() {
utilruntime.Must(imagev1_reflect.AddToScheme(scheme.Scheme)) utilruntime.Must(reflectorv1.AddToScheme(scheme.Scheme))
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme)) utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
utilruntime.Must(imagev1.AddToScheme(scheme.Scheme)) utilruntime.Must(imagev1.AddToScheme(scheme.Scheme))
@ -226,6 +245,7 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
autoGitSpec *imagev1.GitSpec autoGitSpec *imagev1.GitSpec
gitRepoRef *sourcev1.GitRepositoryRef gitRepoRef *sourcev1.GitRepositoryRef
shallowClone bool shallowClone bool
sparseCheckoutDirectory string
lastObserved bool lastObserved bool
wantErr bool wantErr bool
wantRef string wantRef string
@ -275,6 +295,42 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
wantErr: false, wantErr: false,
wantRef: "main", wantRef: "main",
}, },
{
name: "with sparse checkout",
autoGitSpec: &imagev1.GitSpec{
Push: &imagev1.PushSpec{Branch: "main"},
Checkout: &imagev1.GitCheckoutSpec{
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
},
},
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
wantErr: false,
wantRef: "main",
},
{
name: "with sparse checkout for current directory",
autoGitSpec: &imagev1.GitSpec{
Push: &imagev1.PushSpec{Branch: "main"},
Checkout: &imagev1.GitCheckoutSpec{
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
},
},
sparseCheckoutDirectory: "./",
wantErr: false,
wantRef: "main",
},
{
name: "with sparse checkout for different push branch",
autoGitSpec: &imagev1.GitSpec{
Push: &imagev1.PushSpec{Branch: "foo"},
Checkout: &imagev1.GitCheckoutSpec{
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
},
},
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
wantErr: false,
wantRef: "foo",
},
{ {
name: "with last observed commit", name: "with last observed commit",
autoGitSpec: &imagev1.GitSpec{ autoGitSpec: &imagev1.GitSpec{
@ -386,6 +442,9 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
if tt.shallowClone { if tt.shallowClone {
opts = append(opts, WithCheckoutOptionShallowClone()) opts = append(opts, WithCheckoutOptionShallowClone())
} }
if tt.sparseCheckoutDirectory != "" {
opts = append(opts, WithCheckoutOptionSparseCheckoutDirectories(tt.sparseCheckoutDirectory))
}
if tt.lastObserved { if tt.lastObserved {
opts = append(opts, WithCheckoutOptionLastObserved(headRev)) opts = append(opts, WithCheckoutOptionLastObserved(headRev))
} }
@ -429,31 +488,36 @@ func test_sourceManager_CommitAndPush(t *testing.T, proto string) {
checkRefSpecBranch string checkRefSpecBranch string
}{ }{
{ {
name: "push to cloned branch with custom template", name: "push to cloned branch with removed template field",
gitSpec: &imagev1.GitSpec{ gitSpec: &imagev1.GitSpec{
Push: &imagev1.PushSpec{ Push: &imagev1.PushSpec{
Branch: "main", Branch: "main",
}, },
Commit: imagev1.CommitSpec{ Commit: imagev1.CommitSpec{
MessageTemplate: testCommitTemplate, MessageTemplate: testCommitTemplateRemoved,
}, },
}, },
gitRepoReference: &sourcev1.GitRepositoryRef{ gitRepoReference: &sourcev1.GitRepositoryRef{
Branch: "main", Branch: "main",
}, },
latestImage: "helloworld:1.0.1", latestImage: "helloworld:1.0.1",
wantErr: false, wantErr: true,
wantCommitMsg: `Commit summary },
{
Automation: test-ns/test-update name: "push to cloned branch with removed ImageResult field",
gitSpec: &imagev1.GitSpec{
Files: Push: &imagev1.PushSpec{
- deploy.yaml Branch: "main",
Objects: },
- deployment test Commit: imagev1.CommitSpec{
Images: MessageTemplate: testCommitTemplateImageResult,
- helloworld:1.0.1 (policy1) },
`, },
gitRepoReference: &sourcev1.GitRepositoryRef{
Branch: "main",
},
latestImage: "helloworld:1.0.1",
wantErr: true,
}, },
{ {
name: "commit with update ResultV2 template", name: "commit with update ResultV2 template",
@ -636,10 +700,10 @@ Testing: value
workDir := t.TempDir() workDir := t.TempDir()
testNS := "test-ns" testNS := "test-ns"
imgPolicy := &imagev1_reflect.ImagePolicy{} imgPolicy := &reflectorv1.ImagePolicy{}
imgPolicy.Name = "policy1" imgPolicy.Name = "policy1"
imgPolicy.Namespace = testNS imgPolicy.Namespace = testNS
imgPolicy.Status = imagev1_reflect.ImagePolicyStatus{ imgPolicy.Status = reflectorv1.ImagePolicyStatus{
LatestRef: testutil.ImageToRef(tt.latestImage), LatestRef: testutil.ImageToRef(tt.latestImage),
} }
testObjects = append(testObjects, imgPolicy) testObjects = append(testObjects, imgPolicy)
@ -725,12 +789,17 @@ Testing: value
_, err = sm.CheckoutSource(ctx) _, err = sm.CheckoutSource(ctx)
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
policies := []imagev1_reflect.ImagePolicy{*imgPolicy} policies := []reflectorv1.ImagePolicy{*imgPolicy}
result, err := policy.ApplyPolicies(ctx, sm.workingDir, updateAuto, policies) result, err := policy.ApplyPolicies(ctx, sm.workingDir, updateAuto, policies)
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
pushResult, err := sm.CommitAndPush(ctx, updateAuto, result) pushResult, err := sm.CommitAndPush(ctx, updateAuto, result)
g.Expect(err != nil).To(Equal(tt.wantErr)) g.Expect(err != nil).To(Equal(tt.wantErr))
if tt.wantErr {
g.Expect(pushResult).To(BeNil())
g.Expect(err).To(MatchError(ErrRemovedTemplateField))
return
}
if tt.noChange { if tt.noChange {
g.Expect(pushResult).To(BeNil()) g.Expect(pushResult).To(BeNil())
return return
@ -861,10 +930,10 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
// Create ImagePolicy, GitRepository and ImageUpdateAutomation objects. // Create ImagePolicy, GitRepository and ImageUpdateAutomation objects.
latestImage := "helloworld:1.0.1" latestImage := "helloworld:1.0.1"
imgPolicy := &imagev1_reflect.ImagePolicy{} imgPolicy := &reflectorv1.ImagePolicy{}
imgPolicy.Name = "policy1" imgPolicy.Name = "policy1"
imgPolicy.Namespace = testNS imgPolicy.Namespace = testNS
imgPolicy.Status = imagev1_reflect.ImagePolicyStatus{ imgPolicy.Status = reflectorv1.ImagePolicyStatus{
LatestRef: testutil.ImageToRef(latestImage), LatestRef: testutil.ImageToRef(latestImage),
} }
testObjects = append(testObjects, imgPolicy) testObjects = append(testObjects, imgPolicy)
@ -934,7 +1003,7 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
checkoutBranchHead, err := testutil.HeadFromBranch(localRepo, branch) checkoutBranchHead, err := testutil.HeadFromBranch(localRepo, branch)
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
policies := []imagev1_reflect.ImagePolicy{*imgPolicy} policies := []reflectorv1.ImagePolicy{*imgPolicy}
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg) checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
// Pull the new changes to the local repo. // Pull the new changes to the local repo.
@ -969,7 +1038,7 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage) imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage)
g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed()) g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed())
policies = []imagev1_reflect.ImagePolicy{*imgPolicy} policies = []reflectorv1.ImagePolicy{*imgPolicy}
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg) checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
// Pull the new changes to the local repo. // Pull the new changes to the local repo.
@ -1017,7 +1086,7 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage) imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage)
g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed()) g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed())
policies = []imagev1_reflect.ImagePolicy{*imgPolicy} policies = []reflectorv1.ImagePolicy{*imgPolicy}
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg) checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
// Pull the new changes to the local repo. // Pull the new changes to the local repo.
@ -1107,7 +1176,7 @@ Update from image update automation`, "foo", testBranch),
// checkoutAndUpdate performs source checkout, update and push for the given // checkoutAndUpdate performs source checkout, update and push for the given
// arguments. // arguments.
func checkoutAndUpdate(ctx context.Context, g *WithT, kClient client.Client, func checkoutAndUpdate(ctx context.Context, g *WithT, kClient client.Client,
updateAuto *imagev1.ImageUpdateAutomation, policies []imagev1_reflect.ImagePolicy, updateAuto *imagev1.ImageUpdateAutomation, policies []reflectorv1.ImagePolicy,
srcOpts []SourceOption, checkoutOpts []CheckoutOption, pushCfg []PushConfig) { srcOpts []SourceOption, checkoutOpts []CheckoutOption, pushCfg []PushConfig) {
g.THelper() g.THelper()

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package test package testutil
import ( import (
"os" "os"
@ -24,8 +24,10 @@ import (
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
) )
// TODO rewrite this as just doing the diff, so I can test that it // ExpectMatchingDirectories compares two directories, recursively, and
// fails at the right times too. // expects them to match. It will fail if there are files that are
// present in one directory but not the other, or if files that are
// present in both directories have different contents.
func ExpectMatchingDirectories(g *WithT, actualRoot, expectedRoot string) { func ExpectMatchingDirectories(g *WithT, actualRoot, expectedRoot string) {
g.Expect(actualRoot).To(BeADirectory()) g.Expect(actualRoot).To(BeADirectory())
g.Expect(expectedRoot).To(BeADirectory()) g.Expect(expectedRoot).To(BeADirectory())
@ -43,29 +45,28 @@ type Diff interface {
FailedExpectation(g *WithT) FailedExpectation(g *WithT)
} }
type contentdiff struct { type contentDiff struct {
path, actual, expected string path, actual, expected string
} }
func (d contentdiff) Path() string { func (d contentDiff) Path() string {
return d.path return d.path
} }
// Run an expectation that will fail, giving an appropriate error func (d contentDiff) FailedExpectation(g *WithT) {
func (d contentdiff) FailedExpectation(g *WithT) {
g.Expect(d.actual).To(Equal(d.expected)) g.Expect(d.actual).To(Equal(d.expected))
} }
type dirfile struct { type dirFile struct {
abspath, path string abspath, path string
expectedRegularFile bool expectedRegularFile bool
} }
func (d dirfile) Path() string { func (d dirFile) Path() string {
return d.path return d.path
} }
func (d dirfile) FailedExpectation(g *WithT) { func (d dirFile) FailedExpectation(g *WithT) {
if d.expectedRegularFile { if d.expectedRegularFile {
g.Expect(d.path).To(BeARegularFile()) g.Expect(d.path).To(BeARegularFile())
} else { } else {
@ -125,7 +126,7 @@ func DiffDirectories(actual, expected string) (actualonly []string, expectedonly
case actualInfo.IsDir() && expectedInfo.IsDir(): case actualInfo.IsDir() && expectedInfo.IsDir():
return nil // i.e., keep recursing return nil // i.e., keep recursing
case actualInfo.IsDir() || expectedInfo.IsDir(): case actualInfo.IsDir() || expectedInfo.IsDir():
different = append(different, dirfile{path: relPath, abspath: actualPath, expectedRegularFile: actualInfo.IsDir()}) different = append(different, dirFile{path: relPath, abspath: actualPath, expectedRegularFile: actualInfo.IsDir()})
if expectedInfo.IsDir() { if expectedInfo.IsDir() {
return filepath.SkipDir return filepath.SkipDir
} }
@ -143,7 +144,7 @@ func DiffDirectories(actual, expected string) (actualonly []string, expectedonly
panic(err) panic(err)
} }
if string(actualBytes) != string(expectedBytes) { if string(actualBytes) != string(expectedBytes) {
different = append(different, contentdiff{path: relPath, actual: string(actualBytes), expected: string(expectedBytes)}) different = append(different, contentDiff{path: relPath, actual: string(actualBytes), expected: string(expectedBytes)})
} }
return nil return nil
}) })

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package test package testutil
import ( import (
"testing" "testing"

View File

@ -44,8 +44,9 @@ import (
"github.com/fluxcd/pkg/gittestserver" "github.com/fluxcd/pkg/gittestserver"
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/internal/constants" "github.com/fluxcd/image-automation-controller/internal/constants"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
) )
const ( const (
@ -459,7 +460,7 @@ func GetSigningKeyPair(g *WithT, passphrase string) (*openpgp.Entity, []byte) {
return pgpEntity, b.Bytes() return pgpEntity, b.Bytes()
} }
func ImageToRef(image string) *imagev1_reflect.ImageRef { func ImageToRef(image string) *reflectorv1.ImageRef {
var digest string var digest string
if idx := strings.LastIndex(image, "@"); idx != -1 { if idx := strings.LastIndex(image, "@"); idx != -1 {
@ -472,7 +473,7 @@ func ImageToRef(image string) *imagev1_reflect.ImageRef {
image, tag = image[:idx], image[idx+1:] image, tag = image[:idx], image[idx+1:]
} }
return &imagev1_reflect.ImageRef{ return &reflectorv1.ImageRef{
Name: image, Name: image,
Tag: tag, Tag: tag,
Digest: digest, Digest: digest,

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020, 2021 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -28,7 +28,7 @@ import (
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
) )
// ScreeningReader is a kio.Reader that includes only files that are // ScreeningLocalReader is a kio.Reader that includes only files that are
// pertinent to automation. In practice this means looking for a // pertinent to automation. In practice this means looking for a
// particular token in each file, and ignoring those files without the // particular token in each file, and ignoring those files without the
// token. This avoids most problematic cases -- e.g., templates in a // token. This avoids most problematic cases -- e.g., templates in a

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020, 2021 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020, 2021 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@ -1,3 +1,19 @@
/*
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 update package update
import ( import (

View File

@ -1,3 +1,19 @@
/*
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 update package update
import ( import (
@ -55,54 +71,10 @@ type ObjectIdentifier struct {
yaml.ResourceIdentifier yaml.ResourceIdentifier
} }
// Result reports the outcome of an automated update. It has a nested // Result contains the file changes made during the update. It contains
// structure file->objects->images. Different projections (e.g., all // details about the exact changes made to the files and the objects in them.
// the images, regardless of object) are available via methods. // It has a nested structure file->objects->changes.
type Result struct { type Result struct {
Files map[string]FileResult
}
// FileResult gives the updates in a particular file.
type FileResult struct {
Objects map[ObjectIdentifier][]ImageRef
}
// Images returns all the images that were involved in at least one
// update.
func (r Result) Images() []ImageRef {
seen := make(map[ImageRef]struct{})
var result []ImageRef
for _, file := range r.Files {
for _, images := range file.Objects {
for _, ref := range images {
if _, ok := seen[ref]; !ok {
seen[ref] = struct{}{}
result = append(result, ref)
}
}
}
}
return result
}
// Objects returns a map of all the objects against the images updated
// within, regardless of which file they appear in.
func (r Result) Objects() map[ObjectIdentifier][]ImageRef {
result := make(map[ObjectIdentifier][]ImageRef)
for _, file := range r.Files {
for res, refs := range file.Objects {
result[res] = append(result[res], refs...)
}
}
return result
}
// ResultV2 contains Result of update and also the file changes made during the
// update. This extends the Result to include details about the exact changes
// made to the files and the objects in them. It has a nested structure
// file->objects->changes.
type ResultV2 struct {
ImageResult Result
FileChanges map[string]ObjectChanges FileChanges map[string]ObjectChanges
} }
@ -117,9 +89,9 @@ type Change struct {
Setter string Setter string
} }
// AddChange adds changes to Resultv2 for a given file, object and changes // AddChange adds changes to Result for a given file, object and changes
// associated with it. // associated with it.
func (r *ResultV2) AddChange(file string, objectID ObjectIdentifier, changes ...Change) { func (r *Result) AddChange(file string, objectID ObjectIdentifier, changes ...Change) {
if r.FileChanges == nil { if r.FileChanges == nil {
r.FileChanges = map[string]ObjectChanges{} r.FileChanges = map[string]ObjectChanges{}
} }
@ -133,7 +105,7 @@ func (r *ResultV2) AddChange(file string, objectID ObjectIdentifier, changes ...
} }
// Changes returns all the changes that were made in at least one update. // Changes returns all the changes that were made in at least one update.
func (r ResultV2) Changes() []Change { func (r Result) Changes() []Change {
seen := make(map[Change]struct{}) seen := make(map[Change]struct{})
var result []Change var result []Change
for _, objChanges := range r.FileChanges { for _, objChanges := range r.FileChanges {
@ -150,7 +122,7 @@ func (r ResultV2) Changes() []Change {
} }
// Objects returns ObjectChanges, regardless of which file they appear in. // Objects returns ObjectChanges, regardless of which file they appear in.
func (r ResultV2) Objects() ObjectChanges { func (r Result) Objects() ObjectChanges {
result := make(ObjectChanges) result := make(ObjectChanges)
for _, objChanges := range r.FileChanges { for _, objChanges := range r.FileChanges {
for obj, change := range objChanges { for obj, change := range objChanges {

View File

@ -1,3 +1,19 @@
/*
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 update package update
import ( import (
@ -42,7 +58,7 @@ func TestMustRef(t *testing.T) {
}) })
} }
func TestUpdateResults(t *testing.T) { func TestResult(t *testing.T) {
g := NewWithT(t) g := NewWithT(t)
var result Result var result Result
@ -55,57 +71,6 @@ func TestUpdateResults(t *testing.T) {
}}, }},
} }
result = Result{
Files: map[string]FileResult{
"foo.yaml": {
Objects: map[ObjectIdentifier][]ImageRef{
objectNames[0]: {
mustRef("image:v1.0"),
mustRef("other:v2.0"),
},
},
},
"bar.yaml": {
Objects: map[ObjectIdentifier][]ImageRef{
objectNames[1]: {
mustRef("image:v1.0"),
mustRef("other:v2.0"),
},
},
},
},
}
g.Expect(result.Images()).To(Equal([]ImageRef{
mustRef("image:v1.0"),
mustRef("other:v2.0"),
}))
g.Expect(result.Objects()).To(Equal(map[ObjectIdentifier][]ImageRef{
objectNames[0]: {
mustRef("image:v1.0"),
mustRef("other:v2.0"),
},
objectNames[1]: {
mustRef("image:v1.0"),
mustRef("other:v2.0"),
},
}))
}
func TestResultV2(t *testing.T) {
g := NewWithT(t)
var result ResultV2
objectNames := []ObjectIdentifier{
{yaml.ResourceIdentifier{
NameMeta: yaml.NameMeta{Namespace: "ns", Name: "foo"},
}},
{yaml.ResourceIdentifier{
NameMeta: yaml.NameMeta{Namespace: "ns", Name: "bar"},
}},
}
result.AddChange("foo.yaml", objectNames[0], Change{ result.AddChange("foo.yaml", objectNames[0], Change{
OldValue: "aaa", OldValue: "aaa",
NewValue: "bbb", NewValue: "bbb",
@ -117,7 +82,7 @@ func TestResultV2(t *testing.T) {
Setter: "foo-ns:policy", Setter: "foo-ns:policy",
}) })
result = ResultV2{ result = Result{
FileChanges: map[string]ObjectChanges{ FileChanges: map[string]ObjectChanges{
"foo.yaml": { "foo.yaml": {
objectNames[0]: []Change{ objectNames[0]: []Change{

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020, 2021 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -30,12 +30,13 @@ import (
"sigs.k8s.io/kustomize/kyaml/sets" "sigs.k8s.io/kustomize/kyaml/sets"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/internal/constants" "github.com/fluxcd/image-automation-controller/internal/constants"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
) )
const ( const (
// This is preserved from setters2 // K8sCliExtensionKey is preserved from setters2
K8sCliExtensionKey = "x-k8s-cli" K8sCliExtensionKey = "x-k8s-cli"
) )
@ -49,17 +50,9 @@ func init() {
// UpdateWithSetters takes all YAML files from `inpath`, updates any // UpdateWithSetters takes all YAML files from `inpath`, updates any
// that contain an "in scope" image policy marker, and writes files it // that contain an "in scope" image policy marker, and writes files it
// updated (and only those files) back to `outpath`.
func UpdateWithSetters(tracelog logr.Logger, inpath, outpath string, policies []imagev1_reflect.ImagePolicy) (Result, error) {
result, err := UpdateV2WithSetters(tracelog, inpath, outpath, policies)
return result.ImageResult, err
}
// UpdateV2WithSetters takes all YAML files from `inpath`, updates any
// that contain an "in scope" image policy marker, and writes files it
// updated (and only those files) back to `outpath`. It also returns the result // updated (and only those files) back to `outpath`. It also returns the result
// of the changes it made as ResultV2. // of the changes it made as Result.
func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies []imagev1_reflect.ImagePolicy) (ResultV2, error) { func UpdateWithSetters(tracelog logr.Logger, inpath, outpath string, policies []reflectorv1.ImagePolicy) (Result, error) {
// the OpenAPI schema is a package variable in kyaml/openapi. In // the OpenAPI schema is a package variable in kyaml/openapi. In
// lieu of being able to isolate invocations (per // lieu of being able to isolate invocations (per
// https://github.com/kubernetes-sigs/kustomize/issues/3058), I // https://github.com/kubernetes-sigs/kustomize/issues/3058), I
@ -99,11 +92,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
// collect setter defs and setters by going through all the image // collect setter defs and setters by going through all the image
// policies available. // policies available.
result := Result{ var result Result
Files: make(map[string]FileResult),
}
var resultV2 ResultV2
// Compilng the result needs the file, the image ref used, and the // Compilng the result needs the file, the image ref used, and the
// object. Each setter will supply its own name to its callback, // object. Each setter will supply its own name to its callback,
@ -112,7 +101,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
// iterates. // iterates.
imageRefs := make(map[string]imageRef) imageRefs := make(map[string]imageRef)
setAllCallback := func(file, setterName string, node *yaml.RNode, old, new string) { setAllCallback := func(file, setterName string, node *yaml.RNode, old, new string) {
ref, ok := imageRefs[setterName] _, ok := imageRefs[setterName]
if !ok { if !ok {
return return
} }
@ -130,23 +119,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
Setter: setterName, Setter: setterName,
} }
// Append the change for the file and identifier. // Append the change for the file and identifier.
resultV2.AddChange(file, oid, ch) result.AddChange(file, oid, ch)
fileres, ok := result.Files[file]
if !ok {
fileres = FileResult{
Objects: make(map[ObjectIdentifier][]ImageRef),
}
result.Files[file] = fileres
}
objres := fileres.Objects[oid]
for _, n := range objres {
if n == ref {
return
}
}
objres = append(objres, ref)
fileres.Objects[oid] = objres
} }
defs := map[string]spec.Schema{} defs := map[string]spec.Schema{}
@ -163,7 +136,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
image := policy.Status.LatestRef.String() image := policy.Status.LatestRef.String()
r, err := name.ParseReference(image, name.WeakValidation) r, err := name.ParseReference(image, name.WeakValidation)
if err != nil { if err != nil {
return ResultV2{}, fmt.Errorf("encountered invalid image ref %q: %w", image, err) return Result{}, fmt.Errorf("encountered invalid image ref %q: %w", image, err)
} }
ref := imageRef{ ref := imageRef{
Reference: r, Reference: r,
@ -221,12 +194,10 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
// go! // go!
err := pipeline.Execute() err := pipeline.Execute()
if err != nil { if err != nil {
return ResultV2{}, err return Result{}, err
} }
// Combine the results. return result, nil
resultV2.ImageResult = result
return resultV2, nil
} }
// setAll returns a kio.Filter using the supplied SetAllCallback // setAll returns a kio.Filter using the supplied SetAllCallback

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020, 2021 The Flux authors Copyright 2025 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -20,27 +20,25 @@ import (
"testing" "testing"
"github.com/go-logr/logr" "github.com/go-logr/logr"
"github.com/google/go-containerregistry/pkg/name"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
"github.com/fluxcd/image-automation-controller/internal/testutil" "github.com/fluxcd/image-automation-controller/internal/testutil"
"github.com/fluxcd/image-automation-controller/pkg/test"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
) )
func TestUpdateWithSetters(t *testing.T) { func TestUpdateWithSetters(t *testing.T) {
g := NewWithT(t) g := NewWithT(t)
policies := []imagev1_reflect.ImagePolicy{ policies := []reflectorv1.ImagePolicy{
{ {
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: "automation-ns", Namespace: "automation-ns",
Name: "policy", Name: "policy",
}, },
Status: imagev1_reflect.ImagePolicyStatus{ Status: reflectorv1.ImagePolicyStatus{
LatestRef: testutil.ImageToRef("index.repo.fake/updated:v1.0.1"), LatestRef: testutil.ImageToRef("index.repo.fake/updated:v1.0.1"),
}, },
}, },
@ -49,7 +47,7 @@ func TestUpdateWithSetters(t *testing.T) {
Namespace: "automation-ns", Namespace: "automation-ns",
Name: "unchanged", Name: "unchanged",
}, },
Status: imagev1_reflect.ImagePolicyStatus{ Status: reflectorv1.ImagePolicyStatus{
LatestRef: testutil.ImageToRef("image:v1.0.0"), LatestRef: testutil.ImageToRef("image:v1.0.0"),
}, },
}, },
@ -58,16 +56,17 @@ func TestUpdateWithSetters(t *testing.T) {
Namespace: "automation-ns", Namespace: "automation-ns",
Name: "policy-with-digest", Name: "policy-with-digest",
}, },
Status: imagev1_reflect.ImagePolicyStatus{ Status: reflectorv1.ImagePolicyStatus{
LatestRef: testutil.ImageToRef("image:v1.0.0@sha256:6745aaad46d795c9836632e1fb62f24b7e7f4c843144da8e47a5465c411a14be"), LatestRef: testutil.ImageToRef("image:v1.0.0@sha256:6745aaad46d795c9836632e1fb62f24b7e7f4c843144da8e47a5465c411a14be"),
}, },
}, },
} }
// Test Result.
tmp := t.TempDir() tmp := t.TempDir()
result, err := UpdateWithSetters(logr.Discard(), "testdata/setters/original", tmp, policies) result, err := UpdateWithSetters(logr.Discard(), "testdata/setters/original", tmp, policies)
g.Expect(err).ToNot(HaveOccurred()) g.Expect(err).ToNot(HaveOccurred())
test.ExpectMatchingDirectories(g, tmp, "testdata/setters/expected") testutil.ExpectMatchingDirectories(g, tmp, "testdata/setters/expected")
kustomizeResourceID := ObjectIdentifier{yaml.ResourceIdentifier{ kustomizeResourceID := ObjectIdentifier{yaml.ResourceIdentifier{
TypeMeta: yaml.TypeMeta{ TypeMeta: yaml.TypeMeta{
@ -86,55 +85,7 @@ func TestUpdateWithSetters(t *testing.T) {
}, },
}} }}
r, _ := name.ParseReference("index.repo.fake/updated:v1.0.1")
expectedImageRef := imageRef{r, types.NamespacedName{
Name: "policy",
Namespace: "automation-ns",
}}
r, _ = name.ParseReference("image:v1.0.0@sha256:6745aaad46d795c9836632e1fb62f24b7e7f4c843144da8e47a5465c411a14be")
expectedImageRefDigest := imageRef{r, types.NamespacedName{
Name: "policy-with-digest",
Namespace: "automation-ns",
}}
expectedResult := Result{ expectedResult := Result{
Files: map[string]FileResult{
"kustomization.yml": {
Objects: map[ObjectIdentifier][]ImageRef{
kustomizeResourceID: {
expectedImageRef,
expectedImageRefDigest,
},
},
},
"Kustomization": {
Objects: map[ObjectIdentifier][]ImageRef{
kustomizeResourceID: {
expectedImageRef,
},
},
},
"marked.yaml": {
Objects: map[ObjectIdentifier][]ImageRef{
markedResourceID: {
expectedImageRef,
},
},
},
},
}
g.Expect(result).To(Equal(expectedResult))
// Test ResultV2.
tmp2 := t.TempDir()
resultV2, err := UpdateV2WithSetters(logr.Discard(), "testdata/setters/original", tmp2, policies)
g.Expect(err).ToNot(HaveOccurred())
test.ExpectMatchingDirectories(g, tmp2, "testdata/setters/expected")
expectedResultV2 := ResultV2{
ImageResult: expectedResult,
FileChanges: map[string]ObjectChanges{ FileChanges: map[string]ObjectChanges{
"kustomization.yml": { "kustomization.yml": {
kustomizeResourceID: []Change{ kustomizeResourceID: []Change{
@ -186,5 +137,5 @@ func TestUpdateWithSetters(t *testing.T) {
}, },
} }
g.Expect(resultV2).To(Equal(expectedResultV2)) g.Expect(result).To(Equal(expectedResult))
} }

16
main.go
View File

@ -34,7 +34,7 @@ import (
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics" ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2" reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
"github.com/fluxcd/pkg/auth" "github.com/fluxcd/pkg/auth"
cache "github.com/fluxcd/pkg/cache" cache "github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/runtime/acl" "github.com/fluxcd/pkg/runtime/acl"
@ -69,7 +69,7 @@ var (
func init() { func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(imagev1_reflect.AddToScheme(scheme)) utilruntime.Must(reflectorv1.AddToScheme(scheme))
utilruntime.Must(sourcev1.AddToScheme(scheme)) utilruntime.Must(sourcev1.AddToScheme(scheme))
utilruntime.Must(imagev1.AddToScheme(scheme)) utilruntime.Must(imagev1.AddToScheme(scheme))
// +kubebuilder:scaffold:scheme // +kubebuilder:scaffold:scheme
@ -93,12 +93,15 @@ func main() {
watchOptions helper.WatchOptions watchOptions helper.WatchOptions
concurrent int concurrent int
tokenCacheOptions cache.TokenFlags tokenCacheOptions cache.TokenFlags
defaultServiceAccount string
) )
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&eventsAddr, "events-addr", "", "The address of the events receiver.") flag.StringVar(&eventsAddr, "events-addr", "", "The address of the events receiver.")
flag.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.") flag.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.")
flag.IntVar(&concurrent, "concurrent", 4, "The number of concurrent resource reconciles.") flag.IntVar(&concurrent, "concurrent", 4, "The number of concurrent resource reconciles.")
flag.StringVar(&defaultServiceAccount, auth.ControllerFlagDefaultServiceAccount,
"", "Default service account to use for workload identity when not specified in resources.")
flag.StringSliceVar(&git.KexAlgos, "ssh-kex-algos", []string{}, flag.StringSliceVar(&git.KexAlgos, "ssh-kex-algos", []string{},
"The list of key exchange algorithms to use for ssh connections, arranged from most preferred to the least.") "The list of key exchange algorithms to use for ssh connections, arranged from most preferred to the least.")
flag.StringSliceVar(&git.HostKeyAlgos, "ssh-hostkey-algos", []string{}, flag.StringSliceVar(&git.HostKeyAlgos, "ssh-hostkey-algos", []string{},
@ -132,6 +135,15 @@ func main() {
auth.EnableObjectLevelWorkloadIdentity() auth.EnableObjectLevelWorkloadIdentity()
} }
if defaultServiceAccount != "" {
auth.SetDefaultServiceAccount(defaultServiceAccount)
}
if auth.InconsistentObjectLevelConfiguration() {
setupLog.Error(auth.ErrInconsistentObjectLevelConfiguration, "invalid configuration")
os.Exit(1)
}
watchNamespace := "" watchNamespace := ""
if !watchOptions.AllNamespaces { if !watchOptions.AllNamespaces {
watchNamespace = os.Getenv("RUNTIME_NAMESPACE") watchNamespace = os.Getenv("RUNTIME_NAMESPACE")