diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 302ba117..042f5a79 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -5,7 +5,7 @@ updates: directory: "/" labels: ["dependencies"] schedule: - interval: "daily" + interval: "monthly" groups: go-deps: patterns: @@ -26,4 +26,4 @@ updates: patterns: - "*" schedule: - interval: "daily" + interval: "monthly" diff --git a/.github/workflows/backport.yaml b/.github/workflows/backport.yaml index e6613ca3..3114d1dd 100644 --- a/.github/workflows/backport.yaml +++ b/.github/workflows/backport.yaml @@ -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)) steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: ref: ${{ github.event.pull_request.head.sha }} - name: Create backport PRs - uses: korthout/backport-action@be567af183754f6a5d831ae90f648954763f17f5 # v3.1.0 + uses: korthout/backport-action@ca4972adce8039ff995e618f5fc02d1b7961f27a # v3.3.0 # xref: https://github.com/korthout/backport-action#inputs with: # Use token to allow workflows to be triggered for the created PR diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2a90c0b0..f8b8fb6e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -14,14 +14,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup QEMU - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Setup Docker Buildx id: buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Cache Docker layers - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 id: cache with: path: /tmp/.buildx-cache @@ -29,9 +29,9 @@ jobs: restore-keys: | ${{ runner.os }}-buildx-ghcache- - name: Setup Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.x + go-version: 1.25.x cache-dependency-path: | **/go.sum **/go.mod diff --git a/.github/workflows/cifuzz.yaml b/.github/workflows/cifuzz.yaml index eec0329a..f0ad5c98 100644 --- a/.github/workflows/cifuzz.yaml +++ b/.github/workflows/cifuzz.yaml @@ -12,11 +12,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.x + go-version: 1.25.x cache-dependency-path: | **/go.sum **/go.mod diff --git a/.github/workflows/integration-aws.yaml b/.github/workflows/integration-aws.yaml index 1ab3a6b5..7f703a42 100644 --- a/.github/workflows/integration-aws.yaml +++ b/.github/workflows/integration-aws.yaml @@ -20,26 +20,26 @@ jobs: working-directory: ./tests/integration steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Set up Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: 'tests/integration/go.mod' cache-dependency-path: tests/integration/go.sum - name: Setup Terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 - name: configure aws credentials - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1 with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.IRC_E2E_AWS_ASSUME_ROLE_NAME }} role-session-name: IRC_GH_Actions aws-region: ${{ vars.AWS_REGION }} - name: Set up QEMU - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Cache Docker layers - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 id: cache with: path: /tmp/.buildx-cache diff --git a/.github/workflows/integration-azure.yaml b/.github/workflows/integration-azure.yaml index b27e0d22..87d30de8 100644 --- a/.github/workflows/integration-azure.yaml +++ b/.github/workflows/integration-azure.yaml @@ -19,24 +19,24 @@ jobs: working-directory: ./tests/integration steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Set up Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: 'tests/integration/go.mod' cache-dependency-path: tests/integration/go.sum - name: Setup Terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 - name: Authenticate to Azure - uses: Azure/login@a65d910e8af852a8061c627c456678983e180302 # v1.4.6 + uses: Azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v1.4.6 with: creds: '{"clientId":"${{ secrets.IRC_E2E_AZ_ARM_CLIENT_ID }}","clientSecret":"${{ secrets.IRC_E2E_AZ_ARM_CLIENT_SECRET }}","subscriptionId":"${{ secrets.IRC_E2E_AZ_ARM_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.IRC_E2E_AZ_ARM_TENANT_ID }}"}' - name: Set up QEMU - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Cache Docker layers - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 id: cache with: path: /tmp/.buildx-cache diff --git a/.github/workflows/integration-gcp.yaml b/.github/workflows/integration-gcp.yaml index a3150dd3..8588bded 100644 --- a/.github/workflows/integration-gcp.yaml +++ b/.github/workflows/integration-gcp.yaml @@ -19,28 +19,28 @@ jobs: working-directory: ./tests/integration steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Set up Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: 'tests/integration/go.mod' cache-dependency-path: tests/integration/go.sum - name: Setup Terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 - name: Authenticate to Google Cloud - uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f # v2.1.7 + uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 id: 'auth' with: credentials_json: '${{ secrets.IRC_E2E_GOOGLE_CREDENTIALS }}' token_format: 'access_token' - name: Set up gcloud - uses: google-github-actions/setup-gcloud@6189d56e4096ee891640bb02ac264be376592d6a # v2.1.2 + uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1 - name: Set up QEMU - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Cache Docker layers - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 id: cache with: path: /tmp/.buildx-cache @@ -48,13 +48,13 @@ jobs: restore-keys: | ${{ runner.os }}-buildx-ghcache- - name: Log into gcr.io - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: registry: gcr.io username: oauth2accesstoken password: ${{ steps.auth.outputs.access_token }} - name: Log into us-central1-docker.pkg.dev - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: registry: us-central1-docker.pkg.dev username: oauth2accesstoken diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index bbf711c7..6f47a512 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -15,14 +15,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup QEMU - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Setup Docker Buildx id: buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Build multi-arch container image - uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: push: false builder: ${{ steps.buildx.outputs.name }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a49267b0..83d1c5a0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: packages: write # for pushing and signing container images. steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Kustomize uses: fluxcd/pkg/actions/kustomize@main - name: Prepare @@ -42,24 +42,24 @@ jobs: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - name: Setup QEMU - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 - name: Setup Docker Buildx id: buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Login to GitHub Container Registry - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: registry: ghcr.io username: fluxcdbot password: ${{ secrets.GHCR_TOKEN }} - name: Login to Docker Hub - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: username: fluxcdbot password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }} - name: Generate images meta id: meta - uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 + uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 with: images: | fluxcd/${{ env.CONTROLLER }} @@ -68,7 +68,7 @@ jobs: type=raw,value=${{ steps.prep.outputs.VERSION }} - name: Publish images id: build-push - uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: sbom: true provenance: true @@ -79,7 +79,7 @@ jobs: platforms: linux/amd64,linux/arm/v7,linux/arm64 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - - uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 + - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - name: Sign images env: COSIGN_EXPERIMENTAL: 1 @@ -92,11 +92,11 @@ jobs: mkdir -p config/release kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml - - uses: anchore/sbom-action/download-syft@df80a981bc6edbc4e220a492d3cbe9f5547a6e75 # v0.17.9 + - uses: anchore/sbom-action/download-syft@da167eac915b4e86f08b264dbdbc867b61be6f0c # v0.20.5 - name: Create release and SBOM id: run-goreleaser if: startsWith(github.ref, 'refs/tags/v') - uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0 + uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 with: version: latest args: release --clean --skip=validate @@ -123,7 +123,7 @@ jobs: id-token: write # for creating OIDC tokens for signing. contents: write # for uploading attestations to GitHub releases. if: startsWith(github.ref, 'refs/tags/v') - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 with: provenance-name: "provenance.intoto.jsonl" base64-subjects: "${{ needs.release.outputs.hashes }}" @@ -136,7 +136,7 @@ jobs: id-token: write # for creating OIDC tokens for signing. packages: write # for uploading attestations. if: startsWith(github.ref, 'refs/tags/v') - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 with: image: ${{ needs.release.outputs.image_url }} digest: ${{ needs.release.outputs.image_digest }} @@ -151,7 +151,7 @@ jobs: id-token: write # for creating OIDC tokens for signing. packages: write # for uploading attestations. if: startsWith(github.ref, 'refs/tags/v') - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 with: image: ghcr.io/${{ needs.release.outputs.image_url }} digest: ${{ needs.release.outputs.image_digest }} diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 3ba2b19a..0476fbb4 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -18,9 +18,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Run FOSSA scan and upload build data - uses: fossa-contrib/fossa-action@cdc5065bcdee31a32e47d4585df72d66e8e941c2 # v3.0.0 + uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1 with: # FOSSA Push-Only API Token fossa-api-key: 5ee8bf422db1471e0bcf2bcb289185de @@ -31,22 +31,22 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Go - uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.x + go-version: 1.25.x cache-dependency-path: | **/go.sum **/go.mod - name: Initialize CodeQL - uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 + uses: github/codeql-action/init@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11 with: languages: go # xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # xref: https://codeql.github.com/codeql-query-help/go/ queries: security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 + uses: github/codeql-action/autobuild@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 + uses: github/codeql-action/analyze@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11 diff --git a/.github/workflows/sync-labels.yaml b/.github/workflows/sync-labels.yaml index d0c2c881..22925706 100644 --- a/.github/workflows/sync-labels.yaml +++ b/.github/workflows/sync-labels.yaml @@ -17,7 +17,7 @@ jobs: permissions: issues: write steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3 with: # Configuration file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e5f269a..25b69706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,92 @@ # Changelog +## 0.35.2 + +**Release date:** 2025-06-13 + +This prerelease fixes authentication for +[public ECR repositories](https://fluxcd.io/flux/integrations/aws/#for-amazon-public-elastic-container-registry). + +Fixes: +- Fix authentication for public ECR + [#782](https://github.com/fluxcd/image-reflector-controller/pull/782) + +## 0.35.1 + +**Release date:** 2025-06-01 + +This prerelease fixes the ImagePolicy reconciler spamming red-herring +error messages. + +Fixes: +- Fix ImagePolicy reconciler getting triggered when ImageRepository is not ready + [#774](https://github.com/fluxcd/image-reflector-controller/pull/774) +- Fix ImagePolicy reconciler spamming `no tags in database` after a restart + [#776](https://github.com/fluxcd/image-reflector-controller/pull/776) + +## 0.35.0 + +**Release date:** 2025-05-27 + +This prerelease comes with support for object-level workload identity +and image digest reflection. + +### ImageRepository + +ImageRepository API now supports object-level workload identity by setting +`.spec.provider` to one of `aws`, `azure`, or `gcp`, and setting +`.spec.serviceAccountName` to the name of a service account in the same +namespace that has been configured with appropriate cloud permissions. +For this feature to work, the controller feature gate +`ObjectLevelWorkloadIdentity` must be enabled. See a complete guide +[here](https://fluxcd.io/flux/integrations/). + +ImageRepository API now caches registry credentials for cloud providers +by default. This behavior can be disabled or fine-tuned by adjusting the +token cache controller flags (see +[docs](https://fluxcd.io/flux/components/image/options/#image-reflector-flags)). +The token cache also exposes metrics that are documented +[here](https://fluxcd.io/flux/monitoring/metrics/#controller-metrics). + +### ImagePolicy + +ImagePolicy API now supports configuring a digest reflection policy +through the field `.spec.digestReflectionPolicy`. This allows users +to configure the controller to reflect the digest of the latest image +tag in the status of the ImagePolicy resource. See this +[guide](https://fluxcd.io/flux/guides/image-update/#digest-pinning) +for more details. + +### General updates + +The controller now collects the garbage from BadgerDB, the database +where it stores image tags. The interval is 10 minutes by default, +but it can be disabled or fine-tuned, see +[docs](https://fluxcd.io/flux/components/image/options/#image-reflector-flags). + +In addition, the Kubernetes dependencies have been updated to v1.33 +and various other controller dependencies have been updated to their latest +version. The controller is now built with Go 1.24. + +Fixes: +- Downgrade `Masterminds/semver` to v3.3.0 + [#761](https://github.com/fluxcd/image-reflector-controller/pull/761) + +Improvements: +- [RFC-0010] Introduce object-level workload identity and cache credentials + [#760](https://github.com/fluxcd/image-reflector-controller/pull/760) + [#762](https://github.com/fluxcd/image-reflector-controller/pull/762) + [#766](https://github.com/fluxcd/image-reflector-controller/pull/766) +- Store digest of latest image in ImagePolicy status + [#368](https://github.com/fluxcd/image-reflector-controller/pull/368) +- Implement BadgerDB garbage collection + [#757](https://github.com/fluxcd/image-reflector-controller/pull/757) +- Various dependency updates + [#767](https://github.com/fluxcd/image-reflector-controller/pull/767) + [#765](https://github.com/fluxcd/image-reflector-controller/pull/765) + [#764](https://github.com/fluxcd/image-reflector-controller/pull/764) + [#759](https://github.com/fluxcd/image-reflector-controller/pull/759) + ## 0.34.0 **Release date:** 2025-02-13 diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 7031a5c9..a6731190 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -14,7 +14,7 @@ There are a number of dependencies required to be able to run image-reflector-co ## How to run the test suite Prerequisites: -* go >= 1.24 +* go >= 1.25 * kustomize >= 3.1 You can run them by simply doing diff --git a/Dockerfile b/Dockerfile index b9758aad..45eb8a37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG GO_VERSION=1.24 +ARG GO_VERSION=1.25 ARG XX_VERSION=1.6.1 FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx @@ -30,7 +30,7 @@ COPY internal/ internal/ ENV CGO_ENABLED=0 RUN xx-go build -trimpath -a -o image-reflector-controller main.go -FROM alpine:3.21 +FROM alpine:3.22 ARG TARGETPLATFORM diff --git a/Makefile b/Makefile index b390a96a..b74c9b6b 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ BUILD_PLATFORMS ?= linux/amd64 FUZZ_TIME ?= 1m # API (doc) generation utilities -CONTROLLER_GEN_VERSION ?= v0.16.1 +CONTROLLER_GEN_VERSION ?= v0.19.0 GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) diff --git a/api/go.mod b/api/go.mod index 948b513b..bd36d5b0 100644 --- a/api/go.mod +++ b/api/go.mod @@ -1,35 +1,34 @@ module github.com/fluxcd/image-reflector-controller/api -go 1.24.0 +go 1.25.0 require ( - github.com/fluxcd/pkg/apis/acl v0.7.0 - github.com/fluxcd/pkg/apis/meta v1.12.0 - k8s.io/apimachinery v0.33.0 - sigs.k8s.io/controller-runtime v0.21.0 + github.com/fluxcd/pkg/apis/acl v0.9.0 + github.com/fluxcd/pkg/apis/meta v1.20.0 + k8s.io/apimachinery v0.34.0 + sigs.k8s.io/controller-runtime v0.22.0 ) -// Fix CVE-2022-28948 -replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - require ( - github.com/fxamacker/cbor/v2 v2.8.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // 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 - golang.org/x/net v0.40.0 // indirect - golang.org/x/text v0.25.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/text v0.28.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect ) diff --git a/api/go.sum b/api/go.sum index ed0104fb..f72cacd9 100644 --- a/api/go.sum +++ b/api/go.sum @@ -2,19 +2,18 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/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/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg= -github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI= -github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU= -github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA= +github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4= +github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0= +github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +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-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/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -34,8 +33,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-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 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.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/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= @@ -47,16 +47,18 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +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/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -66,26 +68,26 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -97,22 +99,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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= -k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= -k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= -k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE= +k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug= +k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0= +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/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= -sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0= +k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0= +sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI= -sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/api/v1beta1/doc.go b/api/v1beta1/doc.go index 637a2d40..e8e62a5b 100644 --- a/api/v1beta1/doc.go +++ b/api/v1beta1/doc.go @@ -14,10 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package v1beta1 contains API types for the image API group, version -// v1beta1. These types are concerned with reflecting metadata from -// OCI image repositories into a cluster, so they can be consulted for -// e.g., automation. +// Package v1beta1 contains API types for the image v1beta1 API group +// +// Deprecated: v1beta1 is no longer supported, use v1 instead. // // +kubebuilder:object:generate=true // +groupName=image.toolkit.fluxcd.io diff --git a/api/v1beta1/imagepolicy_types.go b/api/v1beta1/imagepolicy_types.go index 177e6591..ee56a3f4 100644 --- a/api/v1beta1/imagepolicy_types.go +++ b/api/v1beta1/imagepolicy_types.go @@ -130,8 +130,7 @@ func SetImagePolicyReadiness(p *ImagePolicy, status metav1.ConditionStatus, reas } // +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="LatestImage",type=string,JSONPath=`.status.latestImage` +// +kubebuilder:skipversion // ImagePolicy is the Schema for the imagepolicies API type ImagePolicy struct { diff --git a/api/v1beta1/imagerepository_types.go b/api/v1beta1/imagerepository_types.go index 93c386fa..09430ac6 100644 --- a/api/v1beta1/imagerepository_types.go +++ b/api/v1beta1/imagerepository_types.go @@ -149,9 +149,7 @@ func (in ImageRepository) GetTimeout() time.Duration { } // +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Last scan",type=string,JSONPath=`.status.lastScanResult.scanTime` -// +kubebuilder:printcolumn:name="Tags",type=string,JSONPath=`.status.lastScanResult.tagCount` +// +kubebuilder:skipversion // ImageRepository is the Schema for the imagerepositories API type ImageRepository struct { diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index bdca2ad6..6c392f29 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright 2023 The Flux authors +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. diff --git a/api/v1beta2/imagepolicy_types.go b/api/v1beta2/imagepolicy_types.go index 66e0d411..17500821 100644 --- a/api/v1beta2/imagepolicy_types.go +++ b/api/v1beta2/imagepolicy_types.go @@ -69,6 +69,11 @@ type ImagePolicySpec struct { // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" // +optional Interval *metav1.Duration `json:"interval,omitempty"` + + // This flag tells the controller to suspend subsequent policy reconciliations. + // It does not apply to already started reconciliations. Defaults to false. + // +optional + Suspend bool `json:"suspend,omitempty"` } // ReflectionPolicy describes a policy for if/when to reflect a value from the registry in a certain resource field. @@ -166,18 +171,6 @@ func (in *ImageRef) String() string { // ImagePolicyStatus defines the observed state of ImagePolicy type ImagePolicyStatus struct { - // LatestImage gives the first in the list of images scanned by - // the image repository, when filtered and ordered according to - // the policy. - // - // Deprecated: Replaced by the composite "latestRef" field. - LatestImage string `json:"latestImage,omitempty"` - // ObservedPreviousImage is the observed previous LatestImage. It is used - // to keep track of the previous and current images. - // - // Deprecated: Replaced by the composite "observedPreviousRef" field. - // +optional - ObservedPreviousImage string `json:"observedPreviousImage,omitempty"` // LatestRef gives the first in the list of images scanned by // the image repository, when filtered and ordered according // to the policy. @@ -190,6 +183,8 @@ type ImagePolicyStatus struct { ObservedGeneration int64 `json:"observedGeneration,omitempty"` // +optional Conditions []metav1.Condition `json:"conditions,omitempty"` + + meta.ReconcileRequestStatus `json:",inline"` } // GetConditions returns the status conditions of the object. @@ -205,7 +200,12 @@ func (in *ImagePolicy) SetConditions(conditions []metav1.Condition) { // +kubebuilder:storageversion // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="LatestImage",type=string,JSONPath=`.status.latestImage` +// +kubebuilder:resource:shortName=imgpol;imagepol +// +kubebuilder:printcolumn:name="Image",type=string,JSONPath=`.status.latestRef.name` +// +kubebuilder:printcolumn:name="Tag",type=string,JSONPath=`.status.latestRef.tag` +// +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="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // ImagePolicy is the Schema for the imagepolicies API type ImagePolicy struct { @@ -226,8 +226,13 @@ func (in *ImagePolicy) GetDigestReflectionPolicy() ReflectionPolicy { func (in *ImagePolicy) GetInterval() time.Duration { if in.GetDigestReflectionPolicy() == ReflectAlways { + if in.Spec.Interval == nil || in.Spec.Interval.Duration == 0 { + return 10 * time.Minute + } + return in.Spec.Interval.Duration } + return 0 } diff --git a/api/v1beta2/imagerepository_types.go b/api/v1beta2/imagerepository_types.go index 6ee27fc8..ebca4ac8 100644 --- a/api/v1beta2/imagerepository_types.go +++ b/api/v1beta2/imagerepository_types.go @@ -28,6 +28,7 @@ import ( const ImageRepositoryKind = "ImageRepository" // Deprecated: Use ImageFinalizer. +// TODO: Remove in v1. const ImageRepositoryFinalizer = ImageFinalizer // ImageRepositorySpec defines the parameters for scanning an image @@ -115,10 +116,26 @@ type ImageRepositorySpec struct { Insecure bool `json:"insecure,omitempty"` } +// ScanResult contains information about the last scan of the image repository. +// TODO: Make all fields except for LatestTags required in v1. type ScanResult struct { - TagCount int `json:"tagCount"` - ScanTime metav1.Time `json:"scanTime,omitempty"` - LatestTags []string `json:"latestTags,omitempty"` + // Revision is a stable hash of the scanned tags. + // +optional + Revision string `json:"revision"` + + // TagCount is the number of tags found in the last scan. + // +required + TagCount int `json:"tagCount"` + + // ScanTime is the time when the last scan was performed. + // +optional + ScanTime metav1.Time `json:"scanTime"` + + // LatestTags is a small sample of the tags found in the last scan. + // It's the first 10 tags when sorting all the tags in descending + // alphabetical order. + // +optional + LatestTags []string `json:"latestTags,omitempty"` } // ImageRepositoryStatus defines the observed state of ImageRepository @@ -197,8 +214,13 @@ func (in ImageRepository) GetRequeueAfter() time.Duration { // +kubebuilder:storageversion // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Last scan",type=string,JSONPath=`.status.lastScanResult.scanTime` +// +kubebuilder:resource:shortName=imgrepo;imagerepo +// +kubebuilder:printcolumn:name="Image",type="string",JSONPath=".spec.image" // +kubebuilder:printcolumn:name="Tags",type=string,JSONPath=`.status.lastScanResult.tagCount` +// +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 scan",type=string,JSONPath=`.status.lastScanResult.scanTime`,priority=1 +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // ImageRepository is the Schema for the imagerepositories API type ImageRepository struct { diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 500fd1e3..71963fc3 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright 2023 The Flux authors +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. @@ -178,6 +178,7 @@ func (in *ImagePolicyStatus) DeepCopyInto(out *ImagePolicyStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + out.ReconcileRequestStatus = in.ReconcileRequestStatus } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePolicyStatus. diff --git a/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml b/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml index cc95c3c5..9b1d34f0 100644 --- a/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml +++ b/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.1 + controller-gen.kubebuilder.io/version: v0.19.0 name: imagepolicies.image.toolkit.fluxcd.io spec: group: image.toolkit.fluxcd.io @@ -11,205 +11,28 @@ spec: kind: ImagePolicy listKind: ImagePolicyList plural: imagepolicies + shortNames: + - imgpol + - imagepol singular: imagepolicy scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .status.latestImage - name: LatestImage + - jsonPath: .status.latestRef.name + name: Image type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: ImagePolicy is the Schema for the imagepolicies 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: |- - ImagePolicySpec defines the parameters for calculating the - ImagePolicy - properties: - filterTags: - description: |- - FilterTags enables filtering for only a subset of tags based on a set of - rules. If no rules are provided, all the tags from the repository will be - ordered and compared. - properties: - extract: - description: |- - Extract allows a capture group to be extracted from the specified regular - expression pattern, useful before tag evaluation. - type: string - pattern: - description: |- - Pattern specifies a regular expression pattern used to filter for image - tags. - type: string - type: object - imageRepositoryRef: - description: |- - ImageRepositoryRef points at the object specifying the image - being scanned - properties: - name: - description: Name of the referent. - type: string - namespace: - description: Namespace of the referent, when not specified it - acts as LocalObjectReference. - type: string - required: - - name - type: object - policy: - description: |- - Policy gives the particulars of the policy to be followed in - selecting the most recent image - properties: - alphabetical: - description: Alphabetical set of rules to use for alphabetical - ordering of the tags. - properties: - order: - default: asc - description: |- - Order specifies the sorting order of the tags. Given the letters of the - alphabet as tags, ascending order would select Z, and descending order - would select A. - enum: - - asc - - desc - type: string - type: object - numerical: - description: Numerical set of rules to use for numerical ordering - of the tags. - properties: - order: - default: asc - description: |- - Order specifies the sorting order of the tags. Given the integer values - from 0 to 9 as tags, ascending order would select 9, and descending order - would select 0. - enum: - - asc - - desc - type: string - type: object - semver: - description: |- - SemVer gives a semantic version range to check against the tags - available. - properties: - range: - description: |- - Range gives a semver range for the image tag; the highest - version within the range that's a tag yields the latest image. - type: string - required: - - range - type: object - type: object - required: - - imageRepositoryRef - - policy - type: object - status: - default: - observedGeneration: -1 - description: ImagePolicyStatus defines the observed state of ImagePolicy - 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 - latestImage: - description: |- - LatestImage gives the first in the list of images scanned by - the image repository, when filtered and ordered according to - the policy. - type: string - observedGeneration: - format: int64 - type: integer - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .status.latestImage - name: LatestImage + - jsonPath: .status.latestRef.tag + name: Tag type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date name: v1beta2 schema: openAPIV3Schema: @@ -346,6 +169,11 @@ spec: - range type: object type: object + suspend: + description: |- + This flag tells the controller to suspend subsequent policy reconciliations. + It does not apply to already started reconciliations. Defaults to false. + type: boolean required: - imageRepositoryRef - policy @@ -420,13 +248,11 @@ spec: - type type: object type: array - latestImage: + lastHandledReconcileAt: description: |- - LatestImage gives the first in the list of images scanned by - the image repository, when filtered and ordered according to - the policy. - - Deprecated: Replaced by the composite "latestRef" field. + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. type: string latestRef: description: |- @@ -450,13 +276,6 @@ spec: observedGeneration: format: int64 type: integer - observedPreviousImage: - description: |- - ObservedPreviousImage is the observed previous LatestImage. It is used - to keep track of the previous and current images. - - Deprecated: Replaced by the composite "observedPreviousRef" field. - type: string observedPreviousRef: description: |- ObservedPreviousRef is the observed previous LatestRef. It is used diff --git a/config/crd/bases/image.toolkit.fluxcd.io_imagerepositories.yaml b/config/crd/bases/image.toolkit.fluxcd.io_imagerepositories.yaml index ef01312d..9d3f266d 100644 --- a/config/crd/bases/image.toolkit.fluxcd.io_imagerepositories.yaml +++ b/config/crd/bases/image.toolkit.fluxcd.io_imagerepositories.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.1 + controller-gen.kubebuilder.io/version: v0.19.0 name: imagerepositories.image.toolkit.fluxcd.io spec: group: image.toolkit.fluxcd.io @@ -11,241 +11,32 @@ spec: kind: ImageRepository listKind: ImageRepositoryList plural: imagerepositories + shortNames: + - imgrepo + - imagerepo singular: imagerepository scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .status.lastScanResult.scanTime - name: Last scan + - jsonPath: .spec.image + name: Image type: string - jsonPath: .status.lastScanResult.tagCount name: Tags type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: ImageRepository is the Schema for the imagerepositories 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: |- - ImageRepositorySpec defines the parameters for scanning an image - repository, e.g., `fluxcd/flux`. - properties: - accessFrom: - description: |- - AccessFrom defines an ACL for allowing cross-namespace references - to the ImageRepository object based on the caller's namespace labels. - properties: - namespaceSelectors: - description: |- - NamespaceSelectors is the list of namespace selectors to which this ACL applies. - Items in this list are evaluated using a logical OR operation. - items: - description: |- - NamespaceSelector selects the namespaces to which this ACL applies. - An empty map of MatchLabels matches all namespaces in a cluster. - properties: - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: array - required: - - namespaceSelectors - type: object - certSecretRef: - description: |- - CertSecretRef can be given the name of a secret containing - either or both of - - - a PEM-encoded client certificate (`certFile`) and private - key (`keyFile`); - - a PEM-encoded CA certificate (`caFile`) - - and whichever are supplied, will be used for connecting to the - registry. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - exclusionList: - description: |- - ExclusionList is a list of regex strings used to exclude certain tags - from being stored in the database. - items: - type: string - type: array - image: - description: Image is the name of the image repository - type: string - interval: - description: |- - Interval is the length of time to wait between - scans of the image repository. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - secretRef: - description: |- - SecretRef can be given the name of a secret containing - credentials to use for the image registry. The secret should be - created with `kubectl create secret docker-registry`, or the - equivalent. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate - the image pull if the service account has attached pull secrets. - maxLength: 253 - type: string - suspend: - description: |- - This flag tells the controller to suspend subsequent image scans. - It does not apply to already started scans. Defaults to false. - type: boolean - timeout: - description: |- - Timeout for image scanning. - Defaults to 'Interval' duration. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - required: - - image - - interval - type: object - status: - default: - observedGeneration: -1 - description: ImageRepositoryStatus defines the observed state of ImageRepository - properties: - canonicalImageName: - description: |- - CanonicalName is the name of the image repository with all the - implied bits made explicit; e.g., `docker.io/library/alpine` - rather than `alpine`. - type: string - 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 - 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 - lastScanResult: - description: LastScanResult contains the number of fetched tags. - properties: - scanTime: - format: date-time - type: string - tagCount: - type: integer - required: - - tagCount - type: object - observedGeneration: - description: ObservedGeneration is the last reconciled generation. - format: int64 - type: integer - type: object - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string - jsonPath: .status.lastScanResult.scanTime name: Last scan + priority: 1 type: string - - jsonPath: .status.lastScanResult.tagCount - name: Tags - type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date name: v1beta2 schema: openAPIV3Schema: @@ -480,13 +271,23 @@ spec: description: LastScanResult contains the number of fetched tags. properties: latestTags: + description: |- + LatestTags is a small sample of the tags found in the last scan. + It's the first 10 tags when sorting all the tags in descending + alphabetical order. items: type: string type: array + revision: + description: Revision is a stable hash of the scanned tags. + type: string scanTime: + description: ScanTime is the time when the last scan was performed. format: date-time type: string tagCount: + description: TagCount is the number of tags found in the last + scan. type: integer required: - tagCount diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index b19b029e..7e725134 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ resources: images: - name: fluxcd/image-reflector-controller newName: fluxcd/image-reflector-controller - newTag: v0.34.0 + newTag: v0.35.2 diff --git a/config/samples/image_v1beta1_imagepolicy.yaml b/config/samples/image_v1beta1_imagepolicy.yaml deleted file mode 100644 index 2c0a2521..00000000 --- a/config/samples/image_v1beta1_imagepolicy.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: image.toolkit.fluxcd.io/v1beta1 -kind: ImagePolicy -metadata: - name: podinfo - namespace: flux-system -spec: - imageRepositoryRef: - name: podinfo - policy: - semver: - range: 5.0.x diff --git a/config/samples/image_v1beta1_imagerepository.yaml b/config/samples/image_v1beta1_imagerepository.yaml deleted file mode 100644 index 460a0f6d..00000000 --- a/config/samples/image_v1beta1_imagerepository.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: image.toolkit.fluxcd.io/v1beta1 -kind: ImageRepository -metadata: - name: podinfo - namespace: flux-system -spec: - image: ghcr.io/stefanprodan/podinfo - interval: 1m0s - accessFrom: - namespaceSelectors: - - matchLabels: - kubernetes.io/metadata.name: flux-system diff --git a/docs/api/v1beta2/image-reflector.md b/docs/api/v1beta2/image-reflector.md index 9170f28e..04b9f6ef 100644 --- a/docs/api/v1beta2/image-reflector.md +++ b/docs/api/v1beta2/image-reflector.md @@ -167,6 +167,19 @@ reflection policy is set to “Always”.
Defaults to 10m.
+suspendThis flag tells the controller to suspend subsequent policy reconciliations. +It does not apply to already started reconciliations. Defaults to false.
+Defaults to 10m.
+suspendThis flag tells the controller to suspend subsequent policy reconciliations. +It does not apply to already started reconciliations. Defaults to false.
+latestImageLatestImage gives the first in the list of images scanned by -the image repository, when filtered and ordered according to -the policy.
-Deprecated: Replaced by the composite “latestRef” field.
-observedPreviousImageObservedPreviousImage is the observed previous LatestImage. It is used -to keep track of the previous and current images.
-Deprecated: Replaced by the composite “observedPreviousRef” field.
-latestRefReconcileRequestStatus
+(Members of ReconcileRequestStatus are embedded into this type.)
+
ScanResult contains information about the last scan of the image repository. +TODO: Make all fields except for LatestTags required in v1.
+revision+ +string + + |
+
+(Optional)
+ Revision is a stable hash of the scanned tags. + |
+
tagCountint |
+ TagCount is the number of tags found in the last scan. |
|
+(Optional)
+ ScanTime is the time when the last scan was performed. |
|
|
+(Optional)
+ LatestTags is a small sample of the tags found in the last scan. +It’s the first 10 tags when sorting all the tags in descending +alphabetical order. |