Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac71dd88a3 | ||
|
|
c5e5dfb8ae | ||
|
|
6ae880501e | ||
|
|
fd547dfe42 | ||
|
|
436dc7920a | ||
|
|
7a8cf63623 | ||
|
|
a6aefab55b | ||
|
|
5e5ee73046 | ||
|
|
8362c88791 | ||
|
|
340a048e8b | ||
|
|
4b2fc84402 | ||
|
|
2673348c2f | ||
|
|
7132eb3435 | ||
|
|
473b02ce5c | ||
|
|
862d9ddb6d | ||
|
|
33b9345883 | ||
|
|
e169a97577 | ||
|
|
4eddf80724 | ||
|
|
99f182be06 | ||
|
|
cf785cebcc | ||
|
|
7ff4c32d16 | ||
|
|
75bf2d608f | ||
|
|
f950198f9d | ||
|
|
2a2201fe56 |
2
.github/workflows/action.yaml
vendored
2
.github/workflows/action.yaml
vendored
@@ -24,6 +24,6 @@ jobs:
|
|||||||
name: action on ${{ matrix.version }}
|
name: action on ${{ matrix.version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup flux
|
- name: Setup flux
|
||||||
uses: ./action
|
uses: ./action
|
||||||
|
|||||||
2
.github/workflows/backport.yaml
vendored
2
.github/workflows/backport.yaml
vendored
@@ -8,6 +8,6 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write # for reading and creating branches.
|
contents: write # for reading and creating branches.
|
||||||
pull-requests: write # for creating pull requests against release branches.
|
pull-requests: write # for creating pull requests against release branches.
|
||||||
uses: fluxcd/gha-workflows/.github/workflows/backport.yaml@v0.4.0
|
uses: fluxcd/gha-workflows/.github/workflows/backport.yaml@v0.8.0
|
||||||
secrets:
|
secrets:
|
||||||
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||||
|
|||||||
24
.github/workflows/conformance.yaml
vendored
24
.github/workflows/conformance.yaml
vendored
@@ -9,7 +9,7 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VERSION: 1.25.x
|
GO_VERSION: 1.26.x
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
conform-kubernetes:
|
conform-kubernetes:
|
||||||
@@ -23,9 +23,9 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
make build
|
make build
|
||||||
- name: Setup Kubernetes
|
- name: Setup Kubernetes
|
||||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
|
||||||
with:
|
with:
|
||||||
version: v0.30.0
|
version: v0.30.0
|
||||||
cluster_name: ${{ steps.prep.outputs.CLUSTER }}
|
cluster_name: ${{ steps.prep.outputs.CLUSTER }}
|
||||||
@@ -76,13 +76,13 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
# Keep this list up-to-date with https://endoflife.date/kubernetes
|
# Keep this list up-to-date with https://endoflife.date/kubernetes
|
||||||
# Available versions can be found with "replicated cluster versions"
|
# Available versions can be found with "replicated cluster versions"
|
||||||
K3S_VERSION: [ 1.32.9, 1.33.5, 1.34.1 ]
|
K3S_VERSION: [ 1.33.7, 1.34.3, 1.35.0 ]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
@@ -97,7 +97,7 @@ jobs:
|
|||||||
KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml"
|
KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml"
|
||||||
echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT
|
echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT
|
||||||
- name: Setup Kustomize
|
- name: Setup Kustomize
|
||||||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/kustomize@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make build-dev
|
run: make build-dev
|
||||||
- name: Create repository
|
- name: Create repository
|
||||||
@@ -168,13 +168,13 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
# Keep this list up-to-date with https://endoflife.date/red-hat-openshift
|
# Keep this list up-to-date with https://endoflife.date/red-hat-openshift
|
||||||
OPENSHIFT_VERSION: [ 4.19.0-okd, 4.20.0-okd ]
|
OPENSHIFT_VERSION: [ 4.20.0-okd ]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
@@ -189,7 +189,7 @@ jobs:
|
|||||||
KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml"
|
KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml"
|
||||||
echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT
|
echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT
|
||||||
- name: Setup Kustomize
|
- name: Setup Kustomize
|
||||||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/kustomize@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make build-dev
|
run: make build-dev
|
||||||
- name: Create repository
|
- name: Create repository
|
||||||
|
|||||||
6
.github/workflows/e2e-azure.yaml
vendored
6
.github/workflows/e2e-azure.yaml
vendored
@@ -29,11 +29,11 @@ jobs:
|
|||||||
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
|
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
|
||||||
steps:
|
steps:
|
||||||
- name: CheckoutD
|
- name: CheckoutD
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.25.x
|
go-version: 1.26.x
|
||||||
cache-dependency-path: tests/integration/go.sum
|
cache-dependency-path: tests/integration/go.sum
|
||||||
- name: Setup Terraform
|
- name: Setup Terraform
|
||||||
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
|
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
|
||||||
|
|||||||
16
.github/workflows/e2e-bootstrap.yaml
vendored
16
.github/workflows/e2e-bootstrap.yaml
vendored
@@ -17,27 +17,27 @@ jobs:
|
|||||||
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
|
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.25.x
|
go-version: 1.26.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
- name: Setup Kubernetes
|
- name: Setup Kubernetes
|
||||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
|
||||||
with:
|
with:
|
||||||
version: v0.30.0
|
version: v0.30.0
|
||||||
cluster_name: kind
|
cluster_name: kind
|
||||||
# The versions below should target the newest Kubernetes version
|
# The versions below should target the newest Kubernetes version
|
||||||
# Keep this up-to-date with https://endoflife.date/kubernetes
|
# Keep this up-to-date with https://endoflife.date/kubernetes
|
||||||
node_image: ghcr.io/fluxcd/kindest/node:v1.32.1-amd64
|
node_image: ghcr.io/fluxcd/kindest/node:v1.33.0-amd64
|
||||||
kubectl_version: v1.32.0
|
kubectl_version: v1.33.0
|
||||||
- name: Setup Kustomize
|
- name: Setup Kustomize
|
||||||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/kustomize@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
- name: Setup yq
|
- name: Setup yq
|
||||||
uses: fluxcd/pkg/actions/yq@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/yq@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make build-dev
|
run: make build-dev
|
||||||
- name: Set outputs
|
- name: Set outputs
|
||||||
|
|||||||
12
.github/workflows/e2e-gcp.yaml
vendored
12
.github/workflows/e2e-gcp.yaml
vendored
@@ -29,11 +29,11 @@ jobs:
|
|||||||
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
|
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.25.x
|
go-version: 1.26.x
|
||||||
cache-dependency-path: tests/integration/go.sum
|
cache-dependency-path: tests/integration/go.sum
|
||||||
- name: Setup Terraform
|
- name: Setup Terraform
|
||||||
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
|
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
|
||||||
@@ -56,11 +56,11 @@ jobs:
|
|||||||
- name: Setup gcloud
|
- name: Setup gcloud
|
||||||
uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1
|
uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1
|
||||||
- name: Setup QEMU
|
- name: Setup QEMU
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||||
- name: Setup Docker Buildx
|
- name: Setup Docker Buildx
|
||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||||
- name: Log into us-central1-docker.pkg.dev
|
- name: Log into us-central1-docker.pkg.dev
|
||||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||||
with:
|
with:
|
||||||
registry: us-central1-docker.pkg.dev
|
registry: us-central1-docker.pkg.dev
|
||||||
username: oauth2accesstoken
|
username: oauth2accesstoken
|
||||||
|
|||||||
14
.github/workflows/e2e.yaml
vendored
14
.github/workflows/e2e.yaml
vendored
@@ -23,16 +23,16 @@ jobs:
|
|||||||
- 5000:5000
|
- 5000:5000
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.25.x
|
go-version: 1.26.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
- name: Setup Kubernetes
|
- name: Setup Kubernetes
|
||||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
|
||||||
with:
|
with:
|
||||||
version: v0.30.0
|
version: v0.30.0
|
||||||
cluster_name: kind
|
cluster_name: kind
|
||||||
@@ -40,13 +40,13 @@ jobs:
|
|||||||
config: .github/kind/config.yaml # disable KIND-net
|
config: .github/kind/config.yaml # disable KIND-net
|
||||||
# The versions below should target the oldest supported Kubernetes version
|
# The versions below should target the oldest supported Kubernetes version
|
||||||
# Keep this up-to-date with https://endoflife.date/kubernetes
|
# Keep this up-to-date with https://endoflife.date/kubernetes
|
||||||
node_image: ghcr.io/fluxcd/kindest/node:v1.32.1-amd64
|
node_image: ghcr.io/fluxcd/kindest/node:v1.33.0-amd64
|
||||||
kubectl_version: v1.32.0
|
kubectl_version: v1.33.0
|
||||||
- name: Setup Calico for network policy
|
- name: Setup Calico for network policy
|
||||||
run: |
|
run: |
|
||||||
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml
|
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml
|
||||||
- name: Setup Kustomize
|
- name: Setup Kustomize
|
||||||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/kustomize@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: make test
|
run: make test
|
||||||
- name: Run e2e tests
|
- name: Run e2e tests
|
||||||
|
|||||||
6
.github/workflows/ossf.yaml
vendored
6
.github/workflows/ossf.yaml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
actions: read
|
actions: read
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Run analysis
|
- name: Run analysis
|
||||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
||||||
with:
|
with:
|
||||||
@@ -28,12 +28,12 @@ jobs:
|
|||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
publish_results: true
|
publish_results: true
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
- name: Upload SARIF results
|
- name: Upload SARIF results
|
||||||
uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
32
.github/workflows/release.yaml
vendored
32
.github/workflows/release.yaml
vendored
@@ -22,35 +22,35 @@ jobs:
|
|||||||
packages: write # needed for ghcr access
|
packages: write # needed for ghcr access
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Unshallow
|
- name: Unshallow
|
||||||
run: git fetch --prune --unshallow
|
run: git fetch --prune --unshallow
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.25.x
|
go-version: 1.26.x
|
||||||
cache: false
|
cache: false
|
||||||
- name: Setup QEMU
|
- name: Setup QEMU
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||||
- name: Setup Docker Buildx
|
- name: Setup Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||||
- name: Setup Syft
|
- name: Setup Syft
|
||||||
uses: anchore/sbom-action/download-syft@f8bdd1d8ac5e901a77a92f111440fdb1b593736b # v0.20.6
|
uses: anchore/sbom-action/download-syft@28d71544de8eaf1b958d335707167c5f783590ad # v0.22.2
|
||||||
- name: Setup Cosign
|
- name: Setup Cosign
|
||||||
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
|
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||||
with:
|
with:
|
||||||
cosign-release: v2.6.1 # TODO: remove after Flux 2.8 with support for cosign v3
|
cosign-release: v2.6.1 # TODO: remove after Flux 2.8 with support for cosign v3
|
||||||
- name: Setup Kustomize
|
- name: Setup Kustomize
|
||||||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/kustomize@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: fluxcdbot
|
username: fluxcdbot
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||||
with:
|
with:
|
||||||
username: fluxcdbot
|
username: fluxcdbot
|
||||||
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
||||||
@@ -63,7 +63,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
kustomize build manifests/crds > all-crds.yaml
|
kustomize build manifests/crds > all-crds.yaml
|
||||||
- name: Generate OpenAPI JSON schemas from CRDs
|
- name: Generate OpenAPI JSON schemas from CRDs
|
||||||
uses: fluxcd/pkg/actions/crdjsonschema@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/crdjsonschema@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
with:
|
with:
|
||||||
crd: all-crds.yaml
|
crd: all-crds.yaml
|
||||||
output: schemas
|
output: schemas
|
||||||
@@ -103,9 +103,9 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
packages: write
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Kustomize
|
- name: Setup Kustomize
|
||||||
uses: fluxcd/pkg/actions/kustomize@bf02f0a2d612cc07e0892166369fa8f63246aabb # main
|
uses: fluxcd/pkg/actions/kustomize@9a8c0edd5da84dc51a585738c67e3a3950d7fbf0 # main
|
||||||
- name: Setup Flux CLI
|
- name: Setup Flux CLI
|
||||||
uses: ./action/
|
uses: ./action/
|
||||||
with:
|
with:
|
||||||
@@ -116,13 +116,13 @@ jobs:
|
|||||||
VERSION=$(flux version --client | awk '{ print $NF }')
|
VERSION=$(flux version --client | awk '{ print $NF }')
|
||||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: fluxcdbot
|
username: fluxcdbot
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||||
with:
|
with:
|
||||||
username: fluxcdbot
|
username: fluxcdbot
|
||||||
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
||||||
@@ -150,7 +150,7 @@ jobs:
|
|||||||
--path="./flux-system" \
|
--path="./flux-system" \
|
||||||
--source=${{ github.repositoryUrl }} \
|
--source=${{ github.repositoryUrl }} \
|
||||||
--revision="${{ github.ref_name }}@sha1:${{ github.sha }}"
|
--revision="${{ github.ref_name }}@sha1:${{ github.sha }}"
|
||||||
- uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
|
- uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||||
with:
|
with:
|
||||||
cosign-release: v2.6.1 # TODO: remove after Flux 2.8 with support for cosign v3
|
cosign-release: v2.6.1 # TODO: remove after Flux 2.8 with support for cosign v3
|
||||||
- name: Sign manifests
|
- name: Sign manifests
|
||||||
|
|||||||
2
.github/workflows/scan.yaml
vendored
2
.github/workflows/scan.yaml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read # for reading the repository code.
|
contents: read # for reading the repository code.
|
||||||
security-events: write # for uploading the CodeQL analysis results.
|
security-events: write # for uploading the CodeQL analysis results.
|
||||||
uses: fluxcd/gha-workflows/.github/workflows/code-scan.yaml@v0.4.0
|
uses: fluxcd/gha-workflows/.github/workflows/code-scan.yaml@v0.8.0
|
||||||
secrets:
|
secrets:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
fossa-token: ${{ secrets.FOSSA_TOKEN }}
|
fossa-token: ${{ secrets.FOSSA_TOKEN }}
|
||||||
|
|||||||
2
.github/workflows/sync-labels.yaml
vendored
2
.github/workflows/sync-labels.yaml
vendored
@@ -12,6 +12,6 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read # for reading the labels file.
|
contents: read # for reading the labels file.
|
||||||
issues: write # for creating and updating labels.
|
issues: write # for creating and updating labels.
|
||||||
uses: fluxcd/gha-workflows/.github/workflows/labels-sync.yaml@v0.4.0
|
uses: fluxcd/gha-workflows/.github/workflows/labels-sync.yaml@v0.8.0
|
||||||
secrets:
|
secrets:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
8
.github/workflows/update.yaml
vendored
8
.github/workflows/update.yaml
vendored
@@ -16,11 +16,11 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.25.x
|
go-version: 1.26.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
@@ -96,7 +96,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
id: cpr
|
id: cpr
|
||||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||||
commit-message: |
|
commit-message: |
|
||||||
|
|||||||
21
.github/workflows/upgrade-fluxcd-pkg.yaml
vendored
Normal file
21
.github/workflows/upgrade-fluxcd-pkg.yaml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: upgrade-fluxcd-pkg
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
pre-release-pkg:
|
||||||
|
description: >-
|
||||||
|
Temporary flag for Flux 2.8: use the flux/v2.8.x pkg branch for main branches
|
||||||
|
because the pkg release branch was cut before the Flux distribution release.
|
||||||
|
Remove this input once Flux 2.8.0 is released.
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
upgrade-fluxcd-pkg:
|
||||||
|
uses: fluxcd/gha-workflows/.github/workflows/upgrade-fluxcd-pkg.yaml@v0.8.0
|
||||||
|
with:
|
||||||
|
pre-release-pkg: ${{ inputs.pre-release-pkg }}
|
||||||
|
secrets:
|
||||||
|
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||||
@@ -68,8 +68,8 @@ for source changes.
|
|||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
|
|
||||||
* go >= 1.25
|
* go >= 1.26
|
||||||
* kubectl >= 1.30
|
* kubectl >= 1.33
|
||||||
* kustomize >= 5.0
|
* kustomize >= 5.0
|
||||||
|
|
||||||
Install the [controller-runtime/envtest](https://github.com/kubernetes-sigs/controller-runtime/tree/master/tools/setup-envtest) binaries with:
|
Install the [controller-runtime/envtest](https://github.com/kubernetes-sigs/controller-runtime/tree/master/tools/setup-envtest) binaries with:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM alpine:3.22 AS builder
|
FROM alpine:3.23 AS builder
|
||||||
|
|
||||||
RUN apk add --no-cache ca-certificates curl
|
RUN apk add --no-cache ca-certificates curl
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ RUN curl -sL https://dl.k8s.io/release/v${KUBECTL_VER}/bin/${ARCH}/kubectl \
|
|||||||
|
|
||||||
RUN kubectl version --client=true
|
RUN kubectl version --client=true
|
||||||
|
|
||||||
FROM alpine:3.22 AS flux-cli
|
FROM alpine:3.23 AS flux-cli
|
||||||
|
|
||||||
RUN apk add --no-cache ca-certificates
|
RUN apk add --no-cache ca-certificates
|
||||||
|
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -17,8 +17,8 @@ rwildcard=$(foreach d,$(wildcard $(addsuffix *,$(1))),$(call rwildcard,$(d)/,$(2
|
|||||||
all: test build
|
all: test build
|
||||||
|
|
||||||
tidy:
|
tidy:
|
||||||
go mod tidy -compat=1.25
|
go mod tidy -compat=1.26
|
||||||
cd tests/integration && go mod tidy -compat=1.25
|
cd tests/integration && go mod tidy -compat=1.26
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ type checkFlags struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var kubernetesConstraints = []string{
|
var kubernetesConstraints = []string{
|
||||||
">=1.32.0-0",
|
">=1.33.0-0",
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkArgs checkFlags
|
var checkArgs checkFlags
|
||||||
|
|||||||
@@ -196,11 +196,14 @@ func getRows(ctx context.Context, kubeclient client.Client, clientListOpts []cli
|
|||||||
|
|
||||||
func addEventsToList(ctx context.Context, kubeclient client.Client, el *corev1.EventList, clientListOpts []client.ListOption) error {
|
func addEventsToList(ctx context.Context, kubeclient client.Client, el *corev1.EventList, clientListOpts []client.ListOption) error {
|
||||||
listOpts := &metav1.ListOptions{}
|
listOpts := &metav1.ListOptions{}
|
||||||
clientListOpts = append(clientListOpts, client.Limit(cmdutil.DefaultChunkSize))
|
|
||||||
err := runtimeresource.FollowContinue(listOpts,
|
err := runtimeresource.FollowContinue(listOpts,
|
||||||
func(options metav1.ListOptions) (runtime.Object, error) {
|
func(options metav1.ListOptions) (runtime.Object, error) {
|
||||||
newEvents := &corev1.EventList{}
|
newEvents := &corev1.EventList{}
|
||||||
if err := kubeclient.List(ctx, newEvents, clientListOpts...); err != nil {
|
opts := append(clientListOpts, client.Limit(cmdutil.DefaultChunkSize))
|
||||||
|
if options.Continue != "" {
|
||||||
|
opts = append(opts, client.Continue(options.Continue))
|
||||||
|
}
|
||||||
|
if err := kubeclient.List(ctx, newEvents, opts...); err != nil {
|
||||||
return nil, fmt.Errorf("error getting events: %w", err)
|
return nil, fmt.Errorf("error getting events: %w", err)
|
||||||
}
|
}
|
||||||
el.Items = append(el.Items, newEvents.Items...)
|
el.Items = append(el.Items, newEvents.Items...)
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/fields"
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
@@ -419,6 +421,108 @@ func createEvent(obj client.Object, eventType, msg, reason string) corev1.Event
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// paginatedClient wraps a client.Client and simulates real Kubernetes API
|
||||||
|
// pagination by splitting List results into pages of pageSize items,
|
||||||
|
// using the ListMeta.Continue token.
|
||||||
|
type paginatedClient struct {
|
||||||
|
client.Client
|
||||||
|
pageSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *paginatedClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
|
||||||
|
listOpts := &client.ListOptions{}
|
||||||
|
listOpts.ApplyOptions(opts)
|
||||||
|
|
||||||
|
// Fetch all results from the underlying client (without Limit/Continue).
|
||||||
|
stripped := make([]client.ListOption, 0, len(opts))
|
||||||
|
for _, o := range opts {
|
||||||
|
if _, ok := o.(client.Limit); ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := o.(client.Continue); ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
stripped = append(stripped, o)
|
||||||
|
}
|
||||||
|
if err := c.Client.List(ctx, list, stripped...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
items, err := meta.ExtractList(list)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the page window based on the Continue token.
|
||||||
|
start := 0
|
||||||
|
if listOpts.Continue != "" {
|
||||||
|
n, err := strconv.Atoi(listOpts.Continue)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid continue token: %w", err)
|
||||||
|
}
|
||||||
|
start = n
|
||||||
|
}
|
||||||
|
if start > len(items) {
|
||||||
|
start = len(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
end := start + c.pageSize
|
||||||
|
if end > len(items) {
|
||||||
|
end = len(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
page := items[start:end]
|
||||||
|
if err := meta.SetList(list, page); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the Continue token when there are more pages.
|
||||||
|
listAccessor, err := meta.ListAccessor(list)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if end < len(items) {
|
||||||
|
listAccessor.SetContinue(strconv.Itoa(end))
|
||||||
|
} else {
|
||||||
|
listAccessor.SetContinue("")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_addEventsToList_pagination(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
objs, err := ssautil.ReadObjects(strings.NewReader(objects))
|
||||||
|
g.Expect(err).To(Not(HaveOccurred()))
|
||||||
|
|
||||||
|
builder := fake.NewClientBuilder().WithScheme(utils.NewScheme())
|
||||||
|
for _, obj := range objs {
|
||||||
|
builder = builder.WithObjects(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
eventList := &corev1.EventList{}
|
||||||
|
for _, obj := range objs {
|
||||||
|
infoEvent := createEvent(obj, eventv1.EventSeverityInfo, "Info Message", "Info Reason")
|
||||||
|
warningEvent := createEvent(obj, eventv1.EventSeverityError, "Error Message", "Error Reason")
|
||||||
|
eventList.Items = append(eventList.Items, infoEvent, warningEvent)
|
||||||
|
}
|
||||||
|
builder = builder.WithLists(eventList)
|
||||||
|
c := builder.Build()
|
||||||
|
|
||||||
|
totalEvents := len(eventList.Items)
|
||||||
|
g.Expect(totalEvents).To(BeNumerically(">", 2), "need more than 2 events to test pagination")
|
||||||
|
|
||||||
|
// Wrap the client to paginate at 2 items per page, forcing multiple
|
||||||
|
// round-trips through FollowContinue.
|
||||||
|
pc := &paginatedClient{Client: c, pageSize: 2}
|
||||||
|
|
||||||
|
el := &corev1.EventList{}
|
||||||
|
err = addEventsToList(context.Background(), pc, el, nil)
|
||||||
|
g.Expect(err).To(Not(HaveOccurred()))
|
||||||
|
g.Expect(el.Items).To(HaveLen(totalEvents),
|
||||||
|
"addEventsToList should collect all events across paginated responses")
|
||||||
|
}
|
||||||
|
|
||||||
func kindNameIndexer(obj client.Object) []string {
|
func kindNameIndexer(obj client.Object) []string {
|
||||||
e, ok := obj.(*corev1.Event)
|
e, ok := obj.(*corev1.Event)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@@ -59,71 +59,82 @@ type APIVersions struct {
|
|||||||
|
|
||||||
// TODO: Update this mapping when new Flux minor versions are released!
|
// TODO: Update this mapping when new Flux minor versions are released!
|
||||||
// latestAPIVersions contains the latest API versions for each GroupKind
|
// latestAPIVersions contains the latest API versions for each GroupKind
|
||||||
// for each supported Flux version. We maintain the latest two minor versions.
|
// for each supported Flux version. The number of latest minor versions
|
||||||
|
// we maintain here must match what's documented here:
|
||||||
|
//
|
||||||
|
// https://fluxcd.io/flux/releases/#supported-releases
|
||||||
var latestAPIVersions = []APIVersions{
|
var latestAPIVersions = []APIVersions{
|
||||||
{
|
{
|
||||||
FluxVersion: "2.7",
|
FluxVersion: "2.8",
|
||||||
LatestVersions: map[schema.GroupKind]string{
|
LatestVersions: flux27LatestAPIVersions,
|
||||||
// source-controller
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.BucketKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.GitRepositoryKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.OCIRepositoryKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmRepositoryKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmChartKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.ExternalArtifactKind}: sourcev1.GroupVersion.Version,
|
|
||||||
|
|
||||||
// kustomize-controller
|
|
||||||
{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind}: kustomizev1.GroupVersion.Version,
|
|
||||||
|
|
||||||
// helm-controller
|
|
||||||
{Group: helmv2.GroupVersion.Group, Kind: helmv2.HelmReleaseKind}: helmv2.GroupVersion.Version,
|
|
||||||
|
|
||||||
// notification-controller
|
|
||||||
{Group: notificationv1.GroupVersion.Group, Kind: notificationv1.ReceiverKind}: notificationv1.GroupVersion.Version,
|
|
||||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.AlertKind}: notificationv1b3.GroupVersion.Version,
|
|
||||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.ProviderKind}: notificationv1b3.GroupVersion.Version,
|
|
||||||
|
|
||||||
// image-reflector-controller
|
|
||||||
{Group: imagev1.GroupVersion.Group, Kind: imagev1.ImageRepositoryKind}: imagev1.GroupVersion.Version,
|
|
||||||
{Group: imagev1.GroupVersion.Group, Kind: imagev1.ImagePolicyKind}: imagev1.GroupVersion.Version,
|
|
||||||
|
|
||||||
// image-automation-controller
|
|
||||||
{Group: imageautov1.GroupVersion.Group, Kind: imageautov1.ImageUpdateAutomationKind}: imageautov1.GroupVersion.Version,
|
|
||||||
|
|
||||||
// source-watcher
|
|
||||||
{Group: swv1b1.GroupVersion.Group, Kind: swv1b1.ArtifactGeneratorKind}: swv1b1.GroupVersion.Version,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
FluxVersion: "2.6",
|
FluxVersion: "2.7",
|
||||||
LatestVersions: map[schema.GroupKind]string{
|
LatestVersions: flux27LatestAPIVersions,
|
||||||
// source-controller
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.BucketKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.GitRepositoryKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.OCIRepositoryKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmRepositoryKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmChartKind}: sourcev1.GroupVersion.Version,
|
|
||||||
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.ExternalArtifactKind}: sourcev1.GroupVersion.Version,
|
|
||||||
|
|
||||||
// kustomize-controller
|
|
||||||
{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind}: kustomizev1.GroupVersion.Version,
|
|
||||||
|
|
||||||
// helm-controller
|
|
||||||
{Group: helmv2.GroupVersion.Group, Kind: helmv2.HelmReleaseKind}: helmv2.GroupVersion.Version,
|
|
||||||
|
|
||||||
// notification-controller
|
|
||||||
{Group: notificationv1.GroupVersion.Group, Kind: notificationv1.ReceiverKind}: notificationv1.GroupVersion.Version,
|
|
||||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.AlertKind}: notificationv1b3.GroupVersion.Version,
|
|
||||||
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.ProviderKind}: notificationv1b3.GroupVersion.Version,
|
|
||||||
|
|
||||||
// image-reflector-controller
|
|
||||||
{Group: imagev1b2.GroupVersion.Group, Kind: imagev1b2.ImageRepositoryKind}: imagev1b2.GroupVersion.Version,
|
|
||||||
{Group: imagev1b2.GroupVersion.Group, Kind: imagev1b2.ImagePolicyKind}: imagev1b2.GroupVersion.Version,
|
|
||||||
|
|
||||||
// image-automation-controller
|
|
||||||
{Group: imageautov1b2.GroupVersion.Group, Kind: imageautov1b2.ImageUpdateAutomationKind}: imageautov1b2.GroupVersion.Version,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
FluxVersion: "2.6",
|
||||||
|
LatestVersions: flux26LatestAPIVersions,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var flux27LatestAPIVersions = map[schema.GroupKind]string{
|
||||||
|
// source-controller
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.BucketKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.GitRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.OCIRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmChartKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.ExternalArtifactKind}: sourcev1.GroupVersion.Version,
|
||||||
|
|
||||||
|
// kustomize-controller
|
||||||
|
{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind}: kustomizev1.GroupVersion.Version,
|
||||||
|
|
||||||
|
// helm-controller
|
||||||
|
{Group: helmv2.GroupVersion.Group, Kind: helmv2.HelmReleaseKind}: helmv2.GroupVersion.Version,
|
||||||
|
|
||||||
|
// notification-controller
|
||||||
|
{Group: notificationv1.GroupVersion.Group, Kind: notificationv1.ReceiverKind}: notificationv1.GroupVersion.Version,
|
||||||
|
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.AlertKind}: notificationv1b3.GroupVersion.Version,
|
||||||
|
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.ProviderKind}: notificationv1b3.GroupVersion.Version,
|
||||||
|
|
||||||
|
// image-reflector-controller
|
||||||
|
{Group: imagev1.GroupVersion.Group, Kind: imagev1.ImageRepositoryKind}: imagev1.GroupVersion.Version,
|
||||||
|
{Group: imagev1.GroupVersion.Group, Kind: imagev1.ImagePolicyKind}: imagev1.GroupVersion.Version,
|
||||||
|
|
||||||
|
// image-automation-controller
|
||||||
|
{Group: imageautov1.GroupVersion.Group, Kind: imageautov1.ImageUpdateAutomationKind}: imageautov1.GroupVersion.Version,
|
||||||
|
|
||||||
|
// source-watcher
|
||||||
|
{Group: swv1b1.GroupVersion.Group, Kind: swv1b1.ArtifactGeneratorKind}: swv1b1.GroupVersion.Version,
|
||||||
|
}
|
||||||
|
|
||||||
|
var flux26LatestAPIVersions = map[schema.GroupKind]string{
|
||||||
|
// source-controller
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.BucketKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.GitRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.OCIRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmRepositoryKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.HelmChartKind}: sourcev1.GroupVersion.Version,
|
||||||
|
{Group: sourcev1.GroupVersion.Group, Kind: sourcev1.ExternalArtifactKind}: sourcev1.GroupVersion.Version,
|
||||||
|
|
||||||
|
// kustomize-controller
|
||||||
|
{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind}: kustomizev1.GroupVersion.Version,
|
||||||
|
|
||||||
|
// helm-controller
|
||||||
|
{Group: helmv2.GroupVersion.Group, Kind: helmv2.HelmReleaseKind}: helmv2.GroupVersion.Version,
|
||||||
|
|
||||||
|
// notification-controller
|
||||||
|
{Group: notificationv1.GroupVersion.Group, Kind: notificationv1.ReceiverKind}: notificationv1.GroupVersion.Version,
|
||||||
|
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.AlertKind}: notificationv1b3.GroupVersion.Version,
|
||||||
|
{Group: notificationv1b3.GroupVersion.Group, Kind: notificationv1b3.ProviderKind}: notificationv1b3.GroupVersion.Version,
|
||||||
|
|
||||||
|
// image-reflector-controller
|
||||||
|
{Group: imagev1b2.GroupVersion.Group, Kind: imagev1b2.ImageRepositoryKind}: imagev1b2.GroupVersion.Version,
|
||||||
|
{Group: imagev1b2.GroupVersion.Group, Kind: imagev1b2.ImagePolicyKind}: imagev1b2.GroupVersion.Version,
|
||||||
|
|
||||||
|
// image-automation-controller
|
||||||
|
{Group: imageautov1b2.GroupVersion.Group, Kind: imageautov1b2.ImageUpdateAutomationKind}: imageautov1b2.GroupVersion.Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
var migrateCmd = &cobra.Command{
|
var migrateCmd = &cobra.Command{
|
||||||
|
|||||||
2
cmd/flux/testdata/check/check_pre.golden
vendored
2
cmd/flux/testdata/check/check_pre.golden
vendored
@@ -1,3 +1,3 @@
|
|||||||
► checking prerequisites
|
► checking prerequisites
|
||||||
✔ Kubernetes {{ .serverVersion }} >=1.32.0-0
|
✔ Kubernetes {{ .serverVersion }} >=1.33.0-0
|
||||||
✔ prerequisites checks passed
|
✔ prerequisites checks passed
|
||||||
|
|||||||
70
go.mod
70
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module github.com/fluxcd/flux2/v2
|
module github.com/fluxcd/flux2/v2
|
||||||
|
|
||||||
go 1.25.0
|
go 1.26.0
|
||||||
|
|
||||||
// Fix CVE-2022-28948.
|
// Fix CVE-2022-28948.
|
||||||
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
|
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
|
||||||
@@ -11,29 +11,29 @@ require (
|
|||||||
github.com/cyphar/filepath-securejoin v0.6.1
|
github.com/cyphar/filepath-securejoin v0.6.1
|
||||||
github.com/distribution/distribution/v3 v3.0.0
|
github.com/distribution/distribution/v3 v3.0.0
|
||||||
github.com/fluxcd/cli-utils v0.37.1-flux.1
|
github.com/fluxcd/cli-utils v0.37.1-flux.1
|
||||||
github.com/fluxcd/go-git-providers v0.25.0
|
github.com/fluxcd/go-git-providers v0.26.0
|
||||||
github.com/fluxcd/helm-controller/api v1.4.5
|
github.com/fluxcd/helm-controller/api v1.5.0
|
||||||
github.com/fluxcd/image-automation-controller/api v1.0.4
|
github.com/fluxcd/image-automation-controller/api v1.1.0
|
||||||
github.com/fluxcd/image-reflector-controller/api v1.0.4
|
github.com/fluxcd/image-reflector-controller/api v1.1.0
|
||||||
github.com/fluxcd/kustomize-controller/api v1.7.3
|
github.com/fluxcd/kustomize-controller/api v1.8.0
|
||||||
github.com/fluxcd/notification-controller/api v1.7.5
|
github.com/fluxcd/notification-controller/api v1.8.0
|
||||||
github.com/fluxcd/pkg/apis/event v0.22.0
|
github.com/fluxcd/pkg/apis/event v0.24.0
|
||||||
github.com/fluxcd/pkg/apis/meta v1.25.0
|
github.com/fluxcd/pkg/apis/meta v1.25.0
|
||||||
github.com/fluxcd/pkg/auth v0.36.0
|
github.com/fluxcd/pkg/auth v0.38.2
|
||||||
github.com/fluxcd/pkg/chartutil v1.21.0
|
github.com/fluxcd/pkg/chartutil v1.22.0
|
||||||
github.com/fluxcd/pkg/envsubst v1.5.0
|
github.com/fluxcd/pkg/envsubst v1.5.0
|
||||||
github.com/fluxcd/pkg/git v0.41.0
|
github.com/fluxcd/pkg/git v0.43.0
|
||||||
github.com/fluxcd/pkg/kustomize v1.25.0
|
github.com/fluxcd/pkg/kustomize v1.27.0
|
||||||
github.com/fluxcd/pkg/oci v0.59.0
|
github.com/fluxcd/pkg/oci v0.60.0
|
||||||
github.com/fluxcd/pkg/runtime v0.96.0
|
github.com/fluxcd/pkg/runtime v0.100.1
|
||||||
github.com/fluxcd/pkg/sourceignore v0.16.0
|
github.com/fluxcd/pkg/sourceignore v0.17.0
|
||||||
github.com/fluxcd/pkg/ssa v0.64.0
|
github.com/fluxcd/pkg/ssa v0.67.1
|
||||||
github.com/fluxcd/pkg/ssh v0.24.0
|
github.com/fluxcd/pkg/ssh v0.24.0
|
||||||
github.com/fluxcd/pkg/tar v0.17.0
|
github.com/fluxcd/pkg/tar v0.17.0
|
||||||
github.com/fluxcd/pkg/version v0.12.0
|
github.com/fluxcd/pkg/version v0.12.0
|
||||||
github.com/fluxcd/source-controller/api v1.7.4
|
github.com/fluxcd/source-controller/api v1.8.0
|
||||||
github.com/fluxcd/source-watcher/api/v2 v2.0.3
|
github.com/fluxcd/source-watcher/api/v2 v2.1.0
|
||||||
github.com/go-git/go-git/v5 v5.16.4
|
github.com/go-git/go-git/v5 v5.16.5
|
||||||
github.com/go-logr/logr v1.4.3
|
github.com/go-logr/logr v1.4.3
|
||||||
github.com/gonvenience/bunt v1.4.2
|
github.com/gonvenience/bunt v1.4.2
|
||||||
github.com/gonvenience/ytbx v1.4.7
|
github.com/gonvenience/ytbx v1.4.7
|
||||||
@@ -46,22 +46,22 @@ require (
|
|||||||
github.com/mattn/go-shellwords v1.0.12
|
github.com/mattn/go-shellwords v1.0.12
|
||||||
github.com/notaryproject/notation-go v1.3.2
|
github.com/notaryproject/notation-go v1.3.2
|
||||||
github.com/olekukonko/tablewriter v0.0.5
|
github.com/olekukonko/tablewriter v0.0.5
|
||||||
github.com/onsi/gomega v1.39.0
|
github.com/onsi/gomega v1.39.1
|
||||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
|
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/theckman/yacspin v0.13.12
|
github.com/theckman/yacspin v0.13.12
|
||||||
golang.org/x/crypto v0.47.0
|
golang.org/x/crypto v0.48.0
|
||||||
golang.org/x/term v0.39.0
|
golang.org/x/term v0.40.0
|
||||||
golang.org/x/text v0.33.0
|
golang.org/x/text v0.34.0
|
||||||
k8s.io/api v0.35.0
|
k8s.io/api v0.35.0
|
||||||
k8s.io/apiextensions-apiserver v0.35.0
|
k8s.io/apiextensions-apiserver v0.35.0
|
||||||
k8s.io/apimachinery v0.35.0
|
k8s.io/apimachinery v0.35.0
|
||||||
k8s.io/cli-runtime v0.35.0
|
k8s.io/cli-runtime v0.35.0
|
||||||
k8s.io/client-go v0.35.0
|
k8s.io/client-go v0.35.0
|
||||||
k8s.io/kubectl v0.35.0
|
k8s.io/kubectl v0.35.0
|
||||||
sigs.k8s.io/controller-runtime v0.23.0
|
sigs.k8s.io/controller-runtime v0.23.1
|
||||||
sigs.k8s.io/kustomize/api v0.21.0
|
sigs.k8s.io/kustomize/api v0.21.1
|
||||||
sigs.k8s.io/kustomize/kyaml v0.21.0
|
sigs.k8s.io/kustomize/kyaml v0.21.1
|
||||||
sigs.k8s.io/yaml v1.6.0
|
sigs.k8s.io/yaml v1.6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ require (
|
|||||||
cloud.google.com/go/auth v0.18.0 // indirect
|
cloud.google.com/go/auth v0.18.0 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||||
code.gitea.io/sdk/gitea v0.22.0 // indirect
|
code.gitea.io/sdk/gitea v0.23.2 // indirect
|
||||||
dario.cat/mergo v1.0.1 // indirect
|
dario.cat/mergo v1.0.1 // indirect
|
||||||
github.com/42wim/httpsig v1.2.3 // indirect
|
github.com/42wim/httpsig v1.2.3 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect
|
||||||
@@ -150,8 +150,8 @@ require (
|
|||||||
github.com/gonvenience/text v1.0.9 // indirect
|
github.com/gonvenience/text v1.0.9 // indirect
|
||||||
github.com/google/btree v1.1.3 // indirect
|
github.com/google/btree v1.1.3 // indirect
|
||||||
github.com/google/gnostic-models v0.7.0 // indirect
|
github.com/google/gnostic-models v0.7.0 // indirect
|
||||||
github.com/google/go-github/v75 v75.0.0 // indirect
|
github.com/google/go-github/v82 v82.0.0 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.2.0 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // 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.11 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||||
@@ -217,7 +217,7 @@ 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
|
||||||
gitlab.com/gitlab-org/api/client-go v0.142.5 // indirect
|
gitlab.com/gitlab-org/api/client-go v1.29.0 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/contrib/bridges/prometheus v0.63.0 // indirect
|
go.opentelemetry.io/contrib/bridges/prometheus v0.63.0 // indirect
|
||||||
go.opentelemetry.io/contrib/exporters/autoexport v0.63.0 // indirect
|
go.opentelemetry.io/contrib/exporters/autoexport v0.63.0 // indirect
|
||||||
@@ -243,10 +243,10 @@ require (
|
|||||||
go.opentelemetry.io/proto/otlp v1.8.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.8.0 // indirect
|
||||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/net v0.49.0 // indirect
|
golang.org/x/net v0.50.0 // indirect
|
||||||
golang.org/x/oauth2 v0.34.0 // indirect
|
golang.org/x/oauth2 v0.35.0 // indirect
|
||||||
golang.org/x/sync v0.19.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.40.0 // indirect
|
golang.org/x/sys v0.41.0 // indirect
|
||||||
golang.org/x/time v0.14.0 // indirect
|
golang.org/x/time v0.14.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
||||||
google.golang.org/api v0.261.0 // indirect
|
google.golang.org/api v0.261.0 // indirect
|
||||||
@@ -259,12 +259,12 @@ require (
|
|||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
helm.sh/helm/v4 v4.1.0 // indirect
|
helm.sh/helm/v4 v4.1.1 // indirect
|
||||||
k8s.io/component-base v0.35.0 // indirect
|
k8s.io/component-base v0.35.0 // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
|
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
|
||||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
|
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // 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/v6 v6.3.0 // indirect
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
158
go.sum
158
go.sum
@@ -4,8 +4,8 @@ cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIi
|
|||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
||||||
code.gitea.io/sdk/gitea v0.22.0 h1:HCKq7bX/HQ85Nw7c/HAhWgRye+vBp5nQOE8Md1+9Ef0=
|
code.gitea.io/sdk/gitea v0.23.2 h1:iJB1FDmLegwfwjX8gotBDHdPSbk/ZR8V9VmEJaVsJYg=
|
||||||
code.gitea.io/sdk/gitea v0.22.0/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM=
|
code.gitea.io/sdk/gitea v0.23.2/go.mod h1:yyF5+GhljqvA30sRDreoyHILruNiy4ASufugzYg0VHM=
|
||||||
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/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
|
github.com/42wim/httpsig v1.2.3 h1:xb0YyWhkYj57SPtfSttIobJUPJZB9as1nsfo7KWVcEs=
|
||||||
@@ -172,58 +172,58 @@ github.com/fluxcd/cli-utils v0.37.1-flux.1 h1:WnG2mHxCPZMj/soIq/S/1zvbrGCJN3GJGb
|
|||||||
github.com/fluxcd/cli-utils v0.37.1-flux.1/go.mod h1:aND5wX3LuTFtB7eUT7vsWr8mmxRVSPR2Wkvbn0SqPfw=
|
github.com/fluxcd/cli-utils v0.37.1-flux.1/go.mod h1:aND5wX3LuTFtB7eUT7vsWr8mmxRVSPR2Wkvbn0SqPfw=
|
||||||
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/go-git-providers v0.25.0 h1:zkVgujjo2VjKXbucrlTyNhHd9x+27oqyghJX9uLwQv4=
|
github.com/fluxcd/go-git-providers v0.26.0 h1:0DUsXc1nS9Fe4n8tXSEUCGemWzHShd66gmotayDPekw=
|
||||||
github.com/fluxcd/go-git-providers v0.25.0/go.mod h1:8Mx5WRYb61FIjOA26DAi4Ls2rZUHSxP8Nl9qkQHDch8=
|
github.com/fluxcd/go-git-providers v0.26.0/go.mod h1:VJDKUOhZwNAIqDF5iPtIpTr/annsDbKMkPpWiDMBdpo=
|
||||||
github.com/fluxcd/helm-controller/api v1.4.5 h1:hMEBtgXUbJjp+ah0jPI3OOQNVngoToOQvTgFgVpAjNg=
|
github.com/fluxcd/helm-controller/api v1.5.0 h1:M82IuZxDiwTinwq9ASBQ4VjPP0dPJwW576GZZk3mqdY=
|
||||||
github.com/fluxcd/helm-controller/api v1.4.5/go.mod h1:rCgx3qhjjtoIH+1EbzFC2vN71/pp0PgMDrZnGCZX5XY=
|
github.com/fluxcd/helm-controller/api v1.5.0/go.mod h1:Yr0y7GKizbvQQGK5wBX6sGCZrTY86AN9n1PNEsji2XE=
|
||||||
github.com/fluxcd/image-automation-controller/api v1.0.4 h1:Fgdy97hXkyh/JFjxLIyq4ZDHsKsa49aumtrvIyjVd08=
|
github.com/fluxcd/image-automation-controller/api v1.1.0 h1:CLPNHQskX0falo4s1suG1ztUe9IGaY9q5ntcz5Fxt9A=
|
||||||
github.com/fluxcd/image-automation-controller/api v1.0.4/go.mod h1:LLBf4XQJAgnpIMlZUwfpVIkCdUtBOi31B6fDbPwBCq4=
|
github.com/fluxcd/image-automation-controller/api v1.1.0/go.mod h1:dIpTDlWgUfjvdGZCNfe8Ht9sCiHwRbJDoIbwfLQ56wc=
|
||||||
github.com/fluxcd/image-reflector-controller/api v1.0.4 h1:/JGpTZf4eMcKG2FpWfP5H7SneSrD5P8EvwGnHiH/WLY=
|
github.com/fluxcd/image-reflector-controller/api v1.1.0 h1:7TtE9DrCnlH1Wn3R3UKXJHNhX/FgS0ejdjFKHzl+XHs=
|
||||||
github.com/fluxcd/image-reflector-controller/api v1.0.4/go.mod h1:5GS4ojHaz+W6hK80WakGIOYk8sn93AyV5X+YOne1XMw=
|
github.com/fluxcd/image-reflector-controller/api v1.1.0/go.mod h1:hLGsqTv3RydJXaApmN+ZtIOHNxlUdmuOJl323x6dsPE=
|
||||||
github.com/fluxcd/kustomize-controller/api v1.7.3 h1:g+C9Il+H33DQi/ZiQ8KpTvL9KXebXnS4oM/0uJ/C8Gw=
|
github.com/fluxcd/kustomize-controller/api v1.8.0 h1:NqDgjqUwotXaHhvd5z46xOhe1O/NPzycXExbuHRmt38=
|
||||||
github.com/fluxcd/kustomize-controller/api v1.7.3/go.mod h1:Yj80JyfQpBUgLhsUZ/c86qcvPGO2+P1VCKsb8fL+L/k=
|
github.com/fluxcd/kustomize-controller/api v1.8.0/go.mod h1:+ZJB/dIGbnSzZ5J/kiJ8n0USmLNAjfeZU6Xfra0oMZA=
|
||||||
github.com/fluxcd/notification-controller/api v1.7.5 h1:6CO5bKyjodiK9exQFOdBcz0XLeo17rrrWQBTJL9NNa8=
|
github.com/fluxcd/notification-controller/api v1.8.0 h1:KF0+Fq8WVtmUUnj66ymPBo11/ZmSrVHES3toJojJ1CA=
|
||||||
github.com/fluxcd/notification-controller/api v1.7.5/go.mod h1:IciwSg8Q0pVtdbsyDyEXx/MxBKWeagxAazpm64C8oCE=
|
github.com/fluxcd/notification-controller/api v1.8.0/go.mod h1:tGlTJS+hSLbgQm1L78hl6N3iWbTerifh1V5Qm8we4Zo=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA=
|
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/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
|
||||||
github.com/fluxcd/pkg/apis/event v0.22.0 h1:nCW0TnneMnscSnj9NlaSKcvyC+436MbY1GyKn/4YnII=
|
github.com/fluxcd/pkg/apis/event v0.24.0 h1:WVPf0FrJ5JExRDDGoo4W0jZgHZt0n4E48/e8b3TSmkA=
|
||||||
github.com/fluxcd/pkg/apis/event v0.22.0/go.mod h1:Hoi4DejaNKVahGkRXqGBjT9h1aKmhc7RCYcsgoTieqc=
|
github.com/fluxcd/pkg/apis/event v0.24.0/go.mod h1:Hoi4DejaNKVahGkRXqGBjT9h1aKmhc7RCYcsgoTieqc=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.15.0 h1:p8wPIxdmn0vy0a664rsE9JKCfnliZz4HUsDcTy4ZOxA=
|
github.com/fluxcd/pkg/apis/kustomize v1.15.0 h1:p8wPIxdmn0vy0a664rsE9JKCfnliZz4HUsDcTy4ZOxA=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.15.0/go.mod h1:XWdsx8P15OiMaQIvmUjYWdmD3zAwhl5q9osl5iCqcOk=
|
github.com/fluxcd/pkg/apis/kustomize v1.15.0/go.mod h1:XWdsx8P15OiMaQIvmUjYWdmD3zAwhl5q9osl5iCqcOk=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.25.0 h1:fmZgMoe7yITGfhFqdOs7w2GOu3Y/2Vvz4+4p/eay3eA=
|
github.com/fluxcd/pkg/apis/meta v1.25.0 h1:fmZgMoe7yITGfhFqdOs7w2GOu3Y/2Vvz4+4p/eay3eA=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.25.0/go.mod h1:1D92RqAet0/n/cH5S0khBXweirHWkw9rCO0V4NCY6xc=
|
github.com/fluxcd/pkg/apis/meta v1.25.0/go.mod h1:1D92RqAet0/n/cH5S0khBXweirHWkw9rCO0V4NCY6xc=
|
||||||
github.com/fluxcd/pkg/auth v0.36.0 h1:4T61EOyRAElhJedwglfa68OxsD6GiNPGGTMZIeYE3sM=
|
github.com/fluxcd/pkg/auth v0.38.2 h1:AjB64oZO1Er3fxJUw1hRbN6J+2Cf0HWgZIOBE5xUtn8=
|
||||||
github.com/fluxcd/pkg/auth v0.36.0/go.mod h1:pRet9dmeOW3iHEh9BwCvhvjEQ5HjQLi4lblaIfR/yJg=
|
github.com/fluxcd/pkg/auth v0.38.2/go.mod h1:038UyC92mnW1mzZ/A2fHJQUpuhPkJzw39ppChuOdYfI=
|
||||||
github.com/fluxcd/pkg/cache v0.13.0 h1:MqtlgOwIVcGKKgV422e39O+KFSVMWuExKeRaMDBjJlk=
|
github.com/fluxcd/pkg/cache v0.13.0 h1:MqtlgOwIVcGKKgV422e39O+KFSVMWuExKeRaMDBjJlk=
|
||||||
github.com/fluxcd/pkg/cache v0.13.0/go.mod h1:0xRZ1hitrIFQ6pl68ke2wZLbIqA2VLzY78HpDo9DVxs=
|
github.com/fluxcd/pkg/cache v0.13.0/go.mod h1:0xRZ1hitrIFQ6pl68ke2wZLbIqA2VLzY78HpDo9DVxs=
|
||||||
github.com/fluxcd/pkg/chartutil v1.21.0 h1:NJYhlekwBwuqMpRgsOlcsJrw2Xq0cBJW0Nmvz2oMluA=
|
github.com/fluxcd/pkg/chartutil v1.22.0 h1:yxhDsAKK0w5Ol4hr1SVnQZI1c83FR9PghVucNEGq4VM=
|
||||||
github.com/fluxcd/pkg/chartutil v1.21.0/go.mod h1:Gv50bF3SS4OvvKCyyIMRkGeNzZk6Fsh4+lAdrjx97T4=
|
github.com/fluxcd/pkg/chartutil v1.22.0/go.mod h1:aw7h410gKTJfk7KchFzv3tZoh6KlwzZFoameLrIEcNg=
|
||||||
github.com/fluxcd/pkg/envsubst v1.5.0 h1:S07mo+MkGhptdHA4pRze5HPKlc8tHxKswNdcMZi1WDY=
|
github.com/fluxcd/pkg/envsubst v1.5.0 h1:S07mo+MkGhptdHA4pRze5HPKlc8tHxKswNdcMZi1WDY=
|
||||||
github.com/fluxcd/pkg/envsubst v1.5.0/go.mod h1:c3a8DYI855sZUubHFYQbjfjop6Wu4/zg1cLyf7SnCes=
|
github.com/fluxcd/pkg/envsubst v1.5.0/go.mod h1:c3a8DYI855sZUubHFYQbjfjop6Wu4/zg1cLyf7SnCes=
|
||||||
github.com/fluxcd/pkg/git v0.41.0 h1:WvvIUFssFDKpRrptJjDf0B4mrUCwhesv1Txu3DzTsl8=
|
github.com/fluxcd/pkg/git v0.43.0 h1:11LKsTHw+yx3rcGSrSbkURcdc4huUv3FxQZhHIAMofc=
|
||||||
github.com/fluxcd/pkg/git v0.41.0/go.mod h1:iqR4eZEhd3gdRSkv+VDP3Qz9WCner3aZ5ClkOUe+3fc=
|
github.com/fluxcd/pkg/git v0.43.0/go.mod h1:cr9eoYLZHKP3NWgJhhJ8pBcllTpl2SbXVoifW37IyIQ=
|
||||||
github.com/fluxcd/pkg/gittestserver v0.24.0 h1:ZIksyENX8yPlB95GJGoUIT171o2oKFJvFSXu+4mEmzU=
|
github.com/fluxcd/pkg/gittestserver v0.25.0 h1:thnS0OOuU2mEA0PjByxrSxrvlvSwVxJSZY1me782Vq4=
|
||||||
github.com/fluxcd/pkg/gittestserver v0.24.0/go.mod h1:9l+gwEfqqe/WxiRvIrQxircgDcXUF3/tw/1Bie/XwJc=
|
github.com/fluxcd/pkg/gittestserver v0.25.0/go.mod h1:cQqa3cOdKdrIDUqV8SCYbIoNw4/a8frJRGofBLv7sWw=
|
||||||
github.com/fluxcd/pkg/kustomize v1.25.0 h1:0jjACHxaMif+RYwrlDDqA09vRtib7WbqU8MmF0k91bM=
|
github.com/fluxcd/pkg/kustomize v1.27.0 h1:bWoWVaHV1ZRo3Ei1JXpY58hJK25WWna+az5jj6zseE0=
|
||||||
github.com/fluxcd/pkg/kustomize v1.25.0/go.mod h1:253Y78WyQJ+cD1krdoysluy9bsm5yee6SdmA4xf1hnk=
|
github.com/fluxcd/pkg/kustomize v1.27.0/go.mod h1:KKb26vz5EApyOrgencDlvixJnuI6cnkWGks95sK9AFs=
|
||||||
github.com/fluxcd/pkg/oci v0.59.0 h1:0b+iy52QEjGE5vZzmlqjlcTTUYtNZ3F70yG6cyKR+Mg=
|
github.com/fluxcd/pkg/oci v0.60.0 h1:uyAoYoj0i9rxFYQchThwfe4i/X0eb5l9wJuDbSAbqGs=
|
||||||
github.com/fluxcd/pkg/oci v0.59.0/go.mod h1:sh3UhBhhKiHBX2Tjnrpq8qPvk28OxPz3hS0iMW6JdOY=
|
github.com/fluxcd/pkg/oci v0.60.0/go.mod h1:5NT4IaYZocOsXLV3IGgj4FRQtSae46DL8Lq3EcDUqME=
|
||||||
github.com/fluxcd/pkg/runtime v0.96.0 h1:sF4ic8131BwbOE+T2pkiXlkr2gCaxAho500zlZJJLck=
|
github.com/fluxcd/pkg/runtime v0.100.1 h1:UiPmgY8Yv7UF06MT5T8AG9uDGNszm75/DQtK6JEhnrM=
|
||||||
github.com/fluxcd/pkg/runtime v0.96.0/go.mod h1:FyjNMFNAERkCsF/muTWJYU9MZOsq/m4Sc4aQk/EgQ9E=
|
github.com/fluxcd/pkg/runtime v0.100.1/go.mod h1:SctSsHvFwUfiOVP1zirP6mo7I8wQtXeWVl2lNQWal88=
|
||||||
github.com/fluxcd/pkg/sourceignore v0.16.0 h1:28+IBmNM1rGNQysiAZXyilFMgS0kno/aJM4zSPgqu2A=
|
github.com/fluxcd/pkg/sourceignore v0.17.0 h1:Z72nruRMhC15zIEpWoDrAcJcJ1El6QDnP/aRDfE4WOA=
|
||||||
github.com/fluxcd/pkg/sourceignore v0.16.0/go.mod h1:Enjrk4gdk8t9VEp0dU3OHvMiS5ZHafZiL4H/FGNluh0=
|
github.com/fluxcd/pkg/sourceignore v0.17.0/go.mod h1:3e/VmYLId0pI/H5sK7W9Ibif+j0Ahns9RxNjDMtTTfY=
|
||||||
github.com/fluxcd/pkg/ssa v0.64.0 h1:B/8VYMIYMeRmolup2HOoWNqXh4UeXi6w2LvXXvl6MZM=
|
github.com/fluxcd/pkg/ssa v0.67.1 h1:wmwrznP+USRUtppKRjAiBx3ayriygRx0IeMdX7z/HaM=
|
||||||
github.com/fluxcd/pkg/ssa v0.64.0/go.mod h1:RjvVjJIoRo1ecsv91yMuiqzO6cpNag80M6MOB/vrJdc=
|
github.com/fluxcd/pkg/ssa v0.67.1/go.mod h1:PFXVjChubQOiWDxalpwh6PzRsEswGqnKwZB4ScoxDx4=
|
||||||
github.com/fluxcd/pkg/ssh v0.24.0 h1:hrPlxs0hhXf32DRqs68VbsXs0XfQMphyRVIk0rYYJa4=
|
github.com/fluxcd/pkg/ssh v0.24.0 h1:hrPlxs0hhXf32DRqs68VbsXs0XfQMphyRVIk0rYYJa4=
|
||||||
github.com/fluxcd/pkg/ssh v0.24.0/go.mod h1:xWammEqalrpurpcMiixJRXtynRQtBEoqheyU5F/vWrg=
|
github.com/fluxcd/pkg/ssh v0.24.0/go.mod h1:xWammEqalrpurpcMiixJRXtynRQtBEoqheyU5F/vWrg=
|
||||||
github.com/fluxcd/pkg/tar v0.17.0 h1:uNxbFXy8ly8C7fJ8D7w3rjTNJFrb4Hp1aY/30XkfvxY=
|
github.com/fluxcd/pkg/tar v0.17.0 h1:uNxbFXy8ly8C7fJ8D7w3rjTNJFrb4Hp1aY/30XkfvxY=
|
||||||
github.com/fluxcd/pkg/tar v0.17.0/go.mod h1:b1xyIRYDD0ket4SV5u0UXYv+ZdN/O/HmIO5jZQdHQls=
|
github.com/fluxcd/pkg/tar v0.17.0/go.mod h1:b1xyIRYDD0ket4SV5u0UXYv+ZdN/O/HmIO5jZQdHQls=
|
||||||
github.com/fluxcd/pkg/version v0.12.0 h1:MGbdbNf2D5wazMqAkNPn+Lh5j+oY0gxQJFTGyet5Hfc=
|
github.com/fluxcd/pkg/version v0.12.0 h1:MGbdbNf2D5wazMqAkNPn+Lh5j+oY0gxQJFTGyet5Hfc=
|
||||||
github.com/fluxcd/pkg/version v0.12.0/go.mod h1:YHdg/78kzf+kCqS+SqSOiUxum5AjxlixiqwpX6AUZB8=
|
github.com/fluxcd/pkg/version v0.12.0/go.mod h1:YHdg/78kzf+kCqS+SqSOiUxum5AjxlixiqwpX6AUZB8=
|
||||||
github.com/fluxcd/source-controller/api v1.7.4 h1:+EOVnRA9LmLxOx7J273l7IOEU39m+Slt/nQGBy69ygs=
|
github.com/fluxcd/source-controller/api v1.8.0 h1:ndrYmcv6ZMcdQHFSUkOrFVDO7h16SfDBSw/DOqf/LPo=
|
||||||
github.com/fluxcd/source-controller/api v1.7.4/go.mod h1:ruf49LEgZRBfcP+eshl2n9SX1MfHayCcViAIGnZcaDY=
|
github.com/fluxcd/source-controller/api v1.8.0/go.mod h1:1O7+sMbqc1+3tPvjmtgFz+bASTl794Y9SxpebHDDSGA=
|
||||||
github.com/fluxcd/source-watcher/api/v2 v2.0.3 h1:SsVGAaMBxzvcgrOz/Kl6c2ybMHVqoiEFwtI+bDuSeSs=
|
github.com/fluxcd/source-watcher/api/v2 v2.1.0 h1:pXKC3VNacjGT6hDyBqP/2kaNlrzNANUn7si5BuW40QE=
|
||||||
github.com/fluxcd/source-watcher/api/v2 v2.0.3/go.mod h1:Nx3QZweVyuhaOtSNrw+oxifG+qrakPvjgNAN9qlUTb0=
|
github.com/fluxcd/source-watcher/api/v2 v2.1.0/go.mod h1:s5ahWDfD0KmpFAbQf3DHCLnWMRkfqt3l5VoCk08LFts=
|
||||||
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.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||||
@@ -242,8 +242,8 @@ github.com/go-git/go-billy/v5 v5.7.0 h1:83lBUJhGWhYp0ngzCMSgllhUSuoHP1iEWYjsPl9n
|
|||||||
github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E=
|
github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
github.com/go-git/go-git/v5 v5.16.4 h1:7ajIEZHZJULcyJebDLo99bGgS0jRrOxzZG4uCk2Yb2Y=
|
github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
|
||||||
github.com/go-git/go-git/v5 v5.16.4/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
|
||||||
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||||
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
@@ -297,21 +297,20 @@ github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76
|
|||||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 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.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I=
|
github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I=
|
||||||
github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM=
|
github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM=
|
||||||
github.com/google/go-github/v75 v75.0.0 h1:k7q8Bvg+W5KxRl9Tjq16a9XEgVY1pwuiG5sIL7435Ic=
|
github.com/google/go-github/v82 v82.0.0 h1:OH09ESON2QwKCUVMYmMcVu1IFKFoaZHwqYaUtr/MVfk=
|
||||||
github.com/google/go-github/v75 v75.0.0/go.mod h1:H3LUJEA1TCrzuUqtdAQniBNwuKiQIqdGKgBo1/M/uqI=
|
github.com/google/go-github/v82 v82.0.0/go.mod h1:hQ6Xo0VKfL8RZ7z1hSfB4fvISg0QqHOqe9BP0qo+WvM=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
|
||||||
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-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ=
|
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
|
||||||
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
|
||||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
github.com/google/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=
|
||||||
@@ -448,10 +447,10 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
|
|||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||||
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
|
github.com/onsi/ginkgo/v2 v2.28.0 h1:Rrf+lVLmtlBIKv6KrIGJCjyY8N36vDVcutbGJkyqjJc=
|
||||||
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
|
github.com/onsi/ginkgo/v2 v2.28.0/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
|
||||||
github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
|
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
|
||||||
github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
|
||||||
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/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||||
@@ -551,8 +550,8 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI
|
|||||||
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
|
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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
gitlab.com/gitlab-org/api/client-go v0.142.5 h1:zvengEU958Fjwasi1V+9QNRw0viqNKkqUwvFD15XDZI=
|
gitlab.com/gitlab-org/api/client-go v1.29.0 h1:3KnF6vENry/9v9eVrnLi2OfBV0m/WSrwh3RcxgH/hkA=
|
||||||
gitlab.com/gitlab-org/api/client-go v0.142.5/go.mod h1:Ru5IRauphXt9qwmTzJD7ou1dH7Gc6pnsdFWEiMMpmB0=
|
gitlab.com/gitlab-org/api/client-go v1.29.0/go.mod h1:6i3EZtC6gKiTTmDwp+f6r/Yi9OY4AaYubl5B3yXEdHE=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||||
go.opentelemetry.io/contrib/bridges/prometheus v0.63.0 h1:/Rij/t18Y7rUayNg7Id6rPrEnHgorxYabm2E6wUdPP4=
|
go.opentelemetry.io/contrib/bridges/prometheus v0.63.0 h1:/Rij/t18Y7rUayNg7Id6rPrEnHgorxYabm2E6wUdPP4=
|
||||||
@@ -622,15 +621,15 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
|||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||||
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
||||||
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@@ -646,10 +645,10 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -686,8 +685,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -697,8 +696,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
|||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||||
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
|
||||||
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
|
||||||
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=
|
||||||
@@ -709,8 +708,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
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=
|
||||||
@@ -719,10 +718,9 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
|
|||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||||
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||||
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-20191204190536-9bdfabe68543/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=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
@@ -760,8 +758,8 @@ 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=
|
||||||
helm.sh/helm/v4 v4.1.0 h1:ytBbmQ7W2h1BLMyvkexnoG52JEDbYj9LTnnNgKRhiCI=
|
helm.sh/helm/v4 v4.1.1 h1:juO/Vack3pNUBCX0emMvHL1RL27CEWwGyCd3HyP3mPA=
|
||||||
helm.sh/helm/v4 v4.1.0/go.mod h1:yH4qpYvTNBTHnkRSenhi1m7oEFKoN6iK3/rYyFJ00IQ=
|
helm.sh/helm/v4 v4.1.1/go.mod h1:yH4qpYvTNBTHnkRSenhi1m7oEFKoN6iK3/rYyFJ00IQ=
|
||||||
k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY=
|
k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY=
|
||||||
k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA=
|
k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA=
|
||||||
k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4=
|
k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4=
|
||||||
@@ -782,17 +780,17 @@ k8s.io/kubectl v0.35.0 h1:cL/wJKHDe8E8+rP3G7avnymcMg6bH6JEcR5w5uo06wc=
|
|||||||
k8s.io/kubectl v0.35.0/go.mod h1:VR5/TSkYyxZwrRwY5I5dDq6l5KXmiCb+9w8IKplk3Qo=
|
k8s.io/kubectl v0.35.0/go.mod h1:VR5/TSkYyxZwrRwY5I5dDq6l5KXmiCb+9w8IKplk3Qo=
|
||||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
|
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
|
||||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
sigs.k8s.io/controller-runtime v0.23.0 h1:Ubi7klJWiwEWqDY+odSVZiFA0aDSevOCXpa38yCSYu8=
|
sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE=
|
||||||
sigs.k8s.io/controller-runtime v0.23.0/go.mod h1:DBOIr9NsprUqCZ1ZhsuJ0wAnQSIxY/C6VjZbmLgw0j0=
|
sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
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/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||||
sigs.k8s.io/kustomize/api v0.21.0 h1:I7nry5p8iDJbuRdYS7ez8MUvw7XVNPcIP5GkzzuXIIQ=
|
sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs=
|
||||||
sigs.k8s.io/kustomize/api v0.21.0/go.mod h1:XGVQuR5n2pXKWbzXHweZU683pALGw/AMVO4zU4iS8SE=
|
sigs.k8s.io/kustomize/api v0.21.1/go.mod h1:f3wkKByTrgpgltLgySCntrYoq5d3q7aaxveSagwTlwI=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.21.0 h1:7mQAf3dUwf0wBerWJd8rXhVcnkk5Tvn/q91cGkaP6HQ=
|
sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7fI=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.21.0/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ=
|
sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ=
|
||||||
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/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs=
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.5/helm-controller.crds.yaml
|
- https://github.com/fluxcd/helm-controller/releases/download/v1.5.0/helm-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.5/helm-controller.deployment.yaml
|
- https://github.com/fluxcd/helm-controller/releases/download/v1.5.0/helm-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- labels.yaml
|
- labels.yaml
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v1.0.4/image-automation-controller.crds.yaml
|
- https://github.com/fluxcd/image-automation-controller/releases/download/v1.1.0/image-automation-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v1.0.4/image-automation-controller.deployment.yaml
|
- https://github.com/fluxcd/image-automation-controller/releases/download/v1.1.0/image-automation-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- labels.yaml
|
- labels.yaml
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v1.0.4/image-reflector-controller.crds.yaml
|
- https://github.com/fluxcd/image-reflector-controller/releases/download/v1.1.0/image-reflector-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v1.0.4/image-reflector-controller.deployment.yaml
|
- https://github.com/fluxcd/image-reflector-controller/releases/download/v1.1.0/image-reflector-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- labels.yaml
|
- labels.yaml
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.7.3/kustomize-controller.crds.yaml
|
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.0/kustomize-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.7.3/kustomize-controller.deployment.yaml
|
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.0/kustomize-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- labels.yaml
|
- labels.yaml
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.5/notification-controller.crds.yaml
|
- https://github.com/fluxcd/notification-controller/releases/download/v1.8.0/notification-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.5/notification-controller.deployment.yaml
|
- https://github.com/fluxcd/notification-controller/releases/download/v1.8.0/notification-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- labels.yaml
|
- labels.yaml
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.4/source-controller.crds.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v1.8.0/source-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.4/source-controller.deployment.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v1.8.0/source-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- labels.yaml
|
- labels.yaml
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/source-watcher/releases/download/v2.0.3/source-watcher.crds.yaml
|
- https://github.com/fluxcd/source-watcher/releases/download/v2.1.0/source-watcher.crds.yaml
|
||||||
- https://github.com/fluxcd/source-watcher/releases/download/v2.0.3/source-watcher.deployment.yaml
|
- https://github.com/fluxcd/source-watcher/releases/download/v2.1.0/source-watcher.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- labels.yaml
|
- labels.yaml
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v1.7.4/source-controller.crds.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v1.8.0/source-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.7.3/kustomize-controller.crds.yaml
|
- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.0/kustomize-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/helm-controller/releases/download/v1.4.5/helm-controller.crds.yaml
|
- https://github.com/fluxcd/helm-controller/releases/download/v1.5.0/helm-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/notification-controller/releases/download/v1.7.5/notification-controller.crds.yaml
|
- https://github.com/fluxcd/notification-controller/releases/download/v1.8.0/notification-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v1.0.4/image-reflector-controller.crds.yaml
|
- https://github.com/fluxcd/image-reflector-controller/releases/download/v1.1.0/image-reflector-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v1.0.4/image-automation-controller.crds.yaml
|
- https://github.com/fluxcd/image-automation-controller/releases/download/v1.1.0/image-automation-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/source-watcher/releases/download/v2.0.3/source-watcher.crds.yaml
|
- https://github.com/fluxcd/source-watcher/releases/download/v2.1.0/source-watcher.crds.yaml
|
||||||
|
|||||||
@@ -169,19 +169,19 @@ func BuildWithRoot(root, base string) ([]byte, error) {
|
|||||||
return nil, fmt.Errorf("%s not found", konfig.DefaultKustomizationFileName())
|
return nil, fmt.Errorf("%s not found", konfig.DefaultKustomizationFileName())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(hidde): work around for a bug in kustomize causing it to
|
// Convert absolute paths to relative when possible, for kustomize
|
||||||
// not properly handle absolute paths on Windows.
|
// compatibility. If filepath.Rel fails (e.g. paths on different
|
||||||
// Convert the path to a relative path to the working directory
|
// Windows drives), keep the absolute path — kustomize handles
|
||||||
// as a temporary fix:
|
// absolute paths correctly since go-getter was removed.
|
||||||
// https://github.com/kubernetes-sigs/kustomize/issues/2789
|
// See: https://github.com/kubernetes-sigs/kustomize/issues/2789
|
||||||
|
// https://github.com/fluxcd/flux2/issues/1153
|
||||||
if filepath.IsAbs(base) {
|
if filepath.IsAbs(base) {
|
||||||
wd, err := os.Getwd()
|
wd, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
base, err = filepath.Rel(wd, base)
|
if relBase, err := filepath.Rel(wd, base); err == nil {
|
||||||
if err != nil {
|
base = relBase
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,660 +0,0 @@
|
|||||||
# RFC-XXXX Vendor-Agnostic Short-Lived Credentials
|
|
||||||
|
|
||||||
**Status:** provisional
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Status represents the current state of the RFC.
|
|
||||||
Must be one of `provisional`, `implementable`, `implemented`, `deferred`, `rejected`, `withdrawn`, or `replaced`.
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Creation date:** 2026-02-01
|
|
||||||
|
|
||||||
**Last update:** 2026-02-01
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
In [RFC-0010](https://github.com/fluxcd/flux2/tree/main/rfcs/0010-multi-tenant-workload-identity)
|
|
||||||
we implemented object-level workload identity for cloud providers leveraging
|
|
||||||
`ServiceAccount` tokens. This RFC proposes extending Flux with vendor-agnostic
|
|
||||||
short-lived credentials based on open standards (OIDC and SPIFFE), enabling
|
|
||||||
workload identity authentication with third-party services that are not
|
|
||||||
cloud-provider-managed, such as self-hosted container registries (e.g.
|
|
||||||
[Zot](https://zotregistry.dev/), [Harbor](https://goharbor.io/)). We propose
|
|
||||||
introducing a new spec field `.spec.credential` to the `OCIRepository` and
|
|
||||||
`ImageRepository` APIs, as a structured object with a `type` sub-field
|
|
||||||
supporting three credential types: `ServiceAccountToken`, `SpiffeJWT` and
|
|
||||||
`SpiffeCertificate`.
|
|
||||||
Once demand for other third-party services supporting these credential
|
|
||||||
standards show up for other Flux APIs, this pattern can be extended further.
|
|
||||||
|
|
||||||
## Motivation
|
|
||||||
|
|
||||||
RFC-0010 introduced multi-tenant workload identity for cloud providers (AWS,
|
|
||||||
Azure, GCP) by associating Flux objects with Kubernetes `ServiceAccounts`.
|
|
||||||
However, the current workload identity support is limited to cloud-provider
|
|
||||||
token exchange through their respective Security Token Services (STS). There
|
|
||||||
is a growing need for Flux to support short-lived credentials for third-party
|
|
||||||
services that implement open standards directly, without depending on any
|
|
||||||
cloud provider.
|
|
||||||
|
|
||||||
Several real-world use cases motivate this work:
|
|
||||||
|
|
||||||
- The `Kustomization` and `HelmRelease` APIs already support a vendor-agnostic
|
|
||||||
form of workload identity through the `generic` provider inside
|
|
||||||
`.spec.kubeConfig.configMapRef` -> `.data.provider`. This generic provider
|
|
||||||
issues a `ServiceAccount` token and uses it directly for authentication with
|
|
||||||
remote Kubernetes clusters configured with external OIDC authentication.
|
|
||||||
However, this pattern has not been extended to other Flux APIs.
|
|
||||||
- Container registries such as [Zot](https://github.com/project-zot/zot/pull/3711)
|
|
||||||
and [Harbor](https://github.com/goharbor/harbor/issues/22027) are implementing
|
|
||||||
OIDC workload identity federation, allowing workloads to authenticate using
|
|
||||||
Kubernetes `ServiceAccount` tokens directly, without cloud provider intermediaries.
|
|
||||||
- The [SPIFFE](https://spiffe.io/) standard provides an alternative identity
|
|
||||||
framework that allows workloads to be identified independently of
|
|
||||||
`ServiceAccounts`, enabling use cases where the identity is the Flux object
|
|
||||||
itself (kind, name, namespace) rather than a Kubernetes `ServiceAccount`.
|
|
||||||
|
|
||||||
### Goals
|
|
||||||
|
|
||||||
- Provide vendor-agnostic short-lived credential support in Flux, starting with
|
|
||||||
the `OCIRepository` and `ImageRepository` APIs.
|
|
||||||
- Support Kubernetes `ServiceAccount` tokens as OIDC credentials for
|
|
||||||
authenticating with third-party services that support OIDC federation.
|
|
||||||
- Support SPIFFE SVIDs (both JWT and x509 certificate) as credentials for
|
|
||||||
authenticating with third-party services that support SPIFFE.
|
|
||||||
- Establish a pattern that can be extended to other Flux APIs in the future.
|
|
||||||
|
|
||||||
### Non-Goals
|
|
||||||
|
|
||||||
- It's not a goal to replace or modify the existing cloud-provider workload
|
|
||||||
identity support introduced in RFC-0010. The `.spec.provider` field and its
|
|
||||||
cloud-provider-specific behavior remain unchanged.
|
|
||||||
- It's not a goal to implement a full SPIFFE runtime (SPIRE agent). Instead,
|
|
||||||
Flux controllers will issue short-lived SPIFFE SVIDs directly using a
|
|
||||||
private key provided via a Kubernetes `Secret`.
|
|
||||||
- It's not a goal to support all Flux APIs in the first iteration. The initial
|
|
||||||
implementation targets `OCIRepository` and `ImageRepository`, with other APIs
|
|
||||||
to follow in subsequent releases.
|
|
||||||
|
|
||||||
## Proposal
|
|
||||||
|
|
||||||
We propose introducing a new spec field `.spec.credential` to the `OCIRepository`
|
|
||||||
and `ImageRepository` APIs. This field specifies the type of vendor-agnostic
|
|
||||||
short-lived credential to use for authentication. The field is mutually exclusive
|
|
||||||
with `.spec.provider` (when set to a cloud provider) because "provider" conveys
|
|
||||||
cloud-provider-specific semantics, and because the existing `generic` provider
|
|
||||||
value already has specific behavior in the OCI APIs when used together with
|
|
||||||
`.spec.serviceAccountName` that differs from what is proposed here (see details
|
|
||||||
[here](#why-a-new-field-and-not-specprovider)). The mutual exclusivity is enforced
|
|
||||||
via a CEL validation rule:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
x-kubernetes-validations:
|
|
||||||
- message: spec.credential can only be used with spec.provider 'generic'
|
|
||||||
rule: '!has(self.credential) || !has(self.provider) || self.provider == ''generic'''
|
|
||||||
```
|
|
||||||
|
|
||||||
### Credential Types
|
|
||||||
|
|
||||||
The `.spec.credential` field is a structured object with the following
|
|
||||||
sub-fields:
|
|
||||||
|
|
||||||
- **`.spec.credential.type`** (string, required): The type of vendor-agnostic
|
|
||||||
short-lived credential to use for authentication.
|
|
||||||
- **`.spec.credential.audiences`** (list of strings, optional): Specifies the
|
|
||||||
audiences (`aud` claim) for the issued JWT when `.spec.credential.type` is
|
|
||||||
`ServiceAccountToken` or `SpiffeJWT`. This allows the third-party service to
|
|
||||||
verify that the token was intended for it. If not specified, defaults to
|
|
||||||
`.spec.url` for `OCIRepository` and `.spec.image` for `ImageRepository`.
|
|
||||||
This is analogous to the `Kustomization` and `HelmRelease` APIs, where
|
|
||||||
the audience defaults to the remote cluster address.
|
|
||||||
|
|
||||||
Grouping credential-related fields under `.spec.credential` keeps the main
|
|
||||||
spec clean and allows extending the credential configuration with additional
|
|
||||||
options in the future without polluting the top-level spec.
|
|
||||||
|
|
||||||
The valid values for `.spec.credential.type` are:
|
|
||||||
|
|
||||||
- **`ServiceAccountToken`**: The controller issues a Kubernetes `ServiceAccount`
|
|
||||||
token and uses it directly as a bearer token for authentication. The
|
|
||||||
`ServiceAccount` is determined by the existing `.spec.serviceAccountName`
|
|
||||||
field, which requires the `ObjectLevelWorkloadIdentity` feature gate
|
|
||||||
(introduced in RFC-0010) to be enabled. If `.spec.serviceAccountName` is
|
|
||||||
not set, the controller's own `ServiceAccount` is used. In multi-tenancy
|
|
||||||
lockdown scenarios, the `--default-service-account` controller flag can be
|
|
||||||
used to force a default `ServiceAccount` when `.spec.serviceAccountName` is
|
|
||||||
not specified, preventing the controller's own `ServiceAccount` from being
|
|
||||||
used. The third-party service must be configured with OIDC federation
|
|
||||||
trusting the Kubernetes `ServiceAccount` token issuer. This is the same
|
|
||||||
mechanism already used by the `generic` provider in the `Kustomization` and
|
|
||||||
`HelmRelease` APIs for remote cluster access.
|
|
||||||
|
|
||||||
- **`SpiffeJWT`**: The controller issues a short-lived SPIFFE SVID JWT where
|
|
||||||
the identity (the `sub` claim) is the Flux object itself, encoded as a
|
|
||||||
[SPIFFE ID](https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md)
|
|
||||||
in the format
|
|
||||||
`spiffe://<trust-domain>/<resource>/<namespace>/<name>`, where `<resource>`
|
|
||||||
is the lowercase plural form of the Kubernetes resource type, i.e.
|
|
||||||
`ocirepositories` for `OCIRepository` and `imagerepositories` for
|
|
||||||
`ImageRepository`.
|
|
||||||
The trust domain for the SPIFFE ID is configured via the controller flag
|
|
||||||
`--spiffe-trust-domain`. The `iss` claim is set to the controller flag
|
|
||||||
`--spiffe-issuer`, which third-party services use for OIDC discovery. The
|
|
||||||
JWT is signed using a private key provided via `--spiffe-secret-name`. Unlike
|
|
||||||
`ServiceAccountToken`, this credential type does **not** depend on a
|
|
||||||
Kubernetes `ServiceAccount` for identity. The third-party service must be
|
|
||||||
configured to trust the SPIFFE issuer by having access to the corresponding
|
|
||||||
JWKS document.
|
|
||||||
|
|
||||||
- **`SpiffeCertificate`**: The controller issues a short-lived SPIFFE SVID
|
|
||||||
x509 certificate for client authentication via mTLS. The certificate encodes
|
|
||||||
the same SPIFFE ID as `SpiffeJWT` in the SAN URI field. The certificate is
|
|
||||||
signed using a CA private key and certificate provided via the controller
|
|
||||||
flag `--spiffe-secret-name`. Both `OCIRepository` and `ImageRepository`
|
|
||||||
already support client certificate authentication via mTLS, so this
|
|
||||||
integrates naturally with the existing transport layer. The third-party
|
|
||||||
service must be configured with the CA certificate for trust. Note that
|
|
||||||
`.spec.certSecretRef` may still be optionally used alongside
|
|
||||||
`SpiffeCertificate` for specifying a CA to trust the server's certificate.
|
|
||||||
|
|
||||||
### Controller Flags
|
|
||||||
|
|
||||||
The SPIFFE issuer and cryptographic material are configured as controller-level
|
|
||||||
flags rather than per-object spec fields. This is analogous to the
|
|
||||||
`ServiceAccountToken` credential type, which relies on the cluster-level
|
|
||||||
Kubernetes `ServiceAccount` token issuer PKI — an infrastructure-level concern,
|
|
||||||
not an object-level one. If these inputs were instead provided per-object (e.g.
|
|
||||||
via `.spec.secretRef`), the pattern would degenerate into a secret-based
|
|
||||||
authentication strategy similar to the `github` provider in the Git APIs, which
|
|
||||||
requires a GitHub App private key to be set in `.spec.secretRef`. The goal of
|
|
||||||
this RFC is for Flux objects to have their own identities with short-lived
|
|
||||||
credentials issued from a shared, controller-level PKI, just as Kubernetes
|
|
||||||
`ServiceAccount` tokens are issued from the cluster-level token issuer.
|
|
||||||
|
|
||||||
- **`--spiffe-trust-domain`**: The SPIFFE trust domain used to construct
|
|
||||||
SPIFFE IDs for all SPIFFE credential types. The SPIFFE ID is encoded as
|
|
||||||
`spiffe://<trust-domain>/<resource>/<namespace>/<name>` and is included as the
|
|
||||||
`sub` claim in `SpiffeJWT` tokens and in the SAN URI field of
|
|
||||||
`SpiffeCertificate` x509 certificates. Required when any object uses
|
|
||||||
`SpiffeJWT` or `SpiffeCertificate` as its `.spec.credential`.
|
|
||||||
|
|
||||||
- **`--spiffe-issuer`**: The OIDC issuer URL for `SpiffeJWT` credentials.
|
|
||||||
Used as the `iss` claim in the issued JWTs. Third-party services use this
|
|
||||||
URL for OIDC discovery to fetch the JWKS and verify token signatures.
|
|
||||||
Required when any object uses `SpiffeJWT` as its `.spec.credential`.
|
|
||||||
|
|
||||||
- **`--spiffe-secret-name`**: The name of a Kubernetes TLS `Secret`
|
|
||||||
(`type: kubernetes.io/tls`) in the controller's namespace containing the
|
|
||||||
cryptographic material for issuing SPIFFE SVIDs. This format is compatible
|
|
||||||
with [cert-manager](https://cert-manager.io/), allowing the `Secret` to be
|
|
||||||
automatically provisioned and rotated. The `Secret` must contain:
|
|
||||||
- `tls.key`: The private key. Used for signing JWTs (`SpiffeJWT`) and for
|
|
||||||
signing client certificates (`SpiffeCertificate`).
|
|
||||||
- `tls.crt`: The CA certificate. Used for signing client certificates
|
|
||||||
(`SpiffeCertificate`). Not required for `SpiffeJWT`.
|
|
||||||
|
|
||||||
Required when any object uses `SpiffeJWT` or `SpiffeCertificate` as its
|
|
||||||
`.spec.credential`.
|
|
||||||
|
|
||||||
### User Stories
|
|
||||||
|
|
||||||
#### Story 1
|
|
||||||
|
|
||||||
> As a cluster administrator, I want tenant A to pull OCI artifacts from a
|
|
||||||
> self-hosted Zot registry repository belonging to tenant A using workload
|
|
||||||
> identity, without any cloud provider dependency.
|
|
||||||
|
|
||||||
For example, I would like to have the following configuration:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: source.toolkit.fluxcd.io/v1
|
|
||||||
kind: OCIRepository
|
|
||||||
metadata:
|
|
||||||
name: tenant-a-repo
|
|
||||||
namespace: tenant-a
|
|
||||||
spec:
|
|
||||||
url: oci://zot.zot.svc.cluster.local:5000/tenant-a
|
|
||||||
credential:
|
|
||||||
type: ServiceAccountToken
|
|
||||||
audiences:
|
|
||||||
- zot.zot.svc.cluster.local
|
|
||||||
serviceAccountName: tenant-a-sa
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: tenant-a-sa
|
|
||||||
namespace: tenant-a
|
|
||||||
```
|
|
||||||
|
|
||||||
The Zot registry is configured with OIDC federation trusting the Kubernetes
|
|
||||||
`ServiceAccount` token issuer, and an authorization policy granting the
|
|
||||||
`ServiceAccount` `tenant-a/tenant-a-sa` access only to the `tenant-a`
|
|
||||||
repository.
|
|
||||||
|
|
||||||
#### Story 2
|
|
||||||
|
|
||||||
> As a cluster administrator, I want to authenticate Flux objects with a
|
|
||||||
> SPIFFE-aware service using the identity of the Flux object itself, not a
|
|
||||||
> `ServiceAccount`.
|
|
||||||
|
|
||||||
For example, I would like to have the following configuration:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: source.toolkit.fluxcd.io/v1
|
|
||||||
kind: OCIRepository
|
|
||||||
metadata:
|
|
||||||
name: my-app
|
|
||||||
namespace: production
|
|
||||||
spec:
|
|
||||||
url: oci://registry.example.com/my-app
|
|
||||||
credential:
|
|
||||||
type: SpiffeJWT
|
|
||||||
audiences:
|
|
||||||
- registry.example.com
|
|
||||||
```
|
|
||||||
|
|
||||||
The controller is started with `--spiffe-trust-domain=example.com`.
|
|
||||||
The SPIFFE ID for this object would be
|
|
||||||
`spiffe://example.com/ocirepositories/production/my-app`,
|
|
||||||
and the registry would authorize access based on this identity.
|
|
||||||
|
|
||||||
#### Story 3
|
|
||||||
|
|
||||||
> As a cluster administrator, I want to use mTLS with a SPIFFE certificate
|
|
||||||
> to authenticate with a container registry that supports SPIFFE-based client
|
|
||||||
> certificate authentication.
|
|
||||||
|
|
||||||
For example, I would like to have the following configuration:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: source.toolkit.fluxcd.io/v1
|
|
||||||
kind: OCIRepository
|
|
||||||
metadata:
|
|
||||||
name: secure-app
|
|
||||||
namespace: production
|
|
||||||
spec:
|
|
||||||
url: oci://registry.example.com/secure-app
|
|
||||||
credential:
|
|
||||||
type: SpiffeCertificate
|
|
||||||
```
|
|
||||||
|
|
||||||
The controller is started with `--spiffe-trust-domain=example.com`.
|
|
||||||
It issues a short-lived x509 certificate with the SPIFFE ID
|
|
||||||
`spiffe://example.com/ocirepositories/production/secure-app`
|
|
||||||
in the SAN URI field, and uses it for mTLS authentication with the registry.
|
|
||||||
|
|
||||||
#### Story 4
|
|
||||||
|
|
||||||
> As a cluster administrator, I want to use `ServiceAccount` token
|
|
||||||
> authentication to scan container images from a Harbor registry that supports
|
|
||||||
> OIDC workload identity federation.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: image.toolkit.fluxcd.io/v1
|
|
||||||
kind: ImageRepository
|
|
||||||
metadata:
|
|
||||||
name: my-app
|
|
||||||
namespace: apps
|
|
||||||
spec:
|
|
||||||
image: harbor.example.com/apps/my-app
|
|
||||||
credential:
|
|
||||||
type: ServiceAccountToken
|
|
||||||
audiences:
|
|
||||||
- harbor.example.com
|
|
||||||
serviceAccountName: my-app-sa
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: my-app-sa
|
|
||||||
namespace: apps
|
|
||||||
```
|
|
||||||
|
|
||||||
### Why a New Field and Not `.spec.provider`
|
|
||||||
|
|
||||||
- The word "provider" suggests a cloud provider, which is not what this feature targets.
|
|
||||||
"Credential" better communicates that we are implementing authentication standards, not
|
|
||||||
targeting cloud vendors.
|
|
||||||
- Using only `.spec.provider: generic`, like in the `Kustomization` and `HelmRelease` APIs,
|
|
||||||
is not viable because this value already has specific behavior in the OCI APIs when used
|
|
||||||
together with `.spec.serviceAccountName`, it means: "use `.imagePullSecrets` from the
|
|
||||||
`ServiceAccount` referenced by `.spec.serviceAccountName`".
|
|
||||||
|
|
||||||
The `Kustomization` and `HelmRelease` APIs have a naming inconsistency where
|
|
||||||
`provider: generic` in `.spec.kubeConfig.configMapRef` is used for
|
|
||||||
`ServiceAccountToken`-based authentication with remote clusters. Updating this
|
|
||||||
ConfigMap API is out-of-scope for this RFC; the existing behavior remains
|
|
||||||
unchanged and is considered an exception to the standard proposed here.
|
|
||||||
|
|
||||||
At the end of the day, `generic` is the default provider if none is specified,
|
|
||||||
and it will be the only accepted provider when using `.spec.credential`. This
|
|
||||||
is semantically correct because standard-based credentials are vendor-agnostic
|
|
||||||
by definition, and therefore a "generic" provider conveys the intended meaning.
|
|
||||||
|
|
||||||
### How Trust Should Be Established
|
|
||||||
|
|
||||||
#### For `ServiceAccountToken`
|
|
||||||
|
|
||||||
The Kubernetes `ServiceAccount` token issuer already implements the OIDC
|
|
||||||
Discovery protocol. Third-party services must be configured to trust this
|
|
||||||
issuer by having network access to the OIDC discovery and JWKS endpoints, or
|
|
||||||
by having the JWKS document configured out-of-band. This is the same trust
|
|
||||||
model used by cloud providers for workload identity (see
|
|
||||||
[RFC-0010 Technical Background](https://github.com/fluxcd/flux2/tree/main/rfcs/0010-multi-tenant-workload-identity#technical-background)).
|
|
||||||
For clusters without a built-in public issuer URL, the responsibility of
|
|
||||||
serving the OIDC discovery and JWKS documents can be taken away from the
|
|
||||||
kube-apiserver by using the `--service-account-issuer` and
|
|
||||||
`--service-account-jwks-uri` apiserver flags to point to externally hosted
|
|
||||||
documents. Signing key rotation is also possible through the
|
|
||||||
`--service-account-signing-key-file` and `--service-account-key-file`
|
|
||||||
apiserver flags (see
|
|
||||||
[Flux cross-cloud integration docs](https://fluxcd.io/flux/integrations/cross-cloud/#for-clusters-without-a-built-in-public-issuer-url)).
|
|
||||||
|
|
||||||
#### For `SpiffeJWT`
|
|
||||||
|
|
||||||
`SpiffeJWT` is also OIDC-based — it is an extension of the same OIDC trust
|
|
||||||
model used by `ServiceAccountToken`, but with a separate issuer and key
|
|
||||||
material managed by the cluster administrator rather than by the Kubernetes API
|
|
||||||
server. The trust establishment follows the same OIDC Discovery protocol: users
|
|
||||||
must host the issuer and JWKS documents at the URL specified by
|
|
||||||
`--spiffe-issuer`, reachable from the third-party services they are integrating
|
|
||||||
with. The controller signs the JWTs with the private key from
|
|
||||||
`--spiffe-secret-name`, and the corresponding public key must be available in
|
|
||||||
the JWKS document at the issuer URL.
|
|
||||||
|
|
||||||
#### For `SpiffeCertificate`
|
|
||||||
|
|
||||||
Users must configure the third-party service with the CA certificate provided
|
|
||||||
via `--spiffe-secret-name` so it can verify client certificates issued by the
|
|
||||||
Flux controller.
|
|
||||||
|
|
||||||
### Alternatives
|
|
||||||
|
|
||||||
#### Using `.spec.provider` Instead of `.spec.credential`
|
|
||||||
|
|
||||||
An alternative would be to add the new credential types as values of
|
|
||||||
`.spec.provider` directly (e.g. `provider: serviceaccounttoken`,
|
|
||||||
`provider: spiffejwt`), rather than introducing a separate `.spec.credential`
|
|
||||||
field. However, `.spec.provider` conveys cloud-provider-specific semantics and
|
|
||||||
uses lowercase values like `aws`, `azure`, `gcp` — mixing vendor-agnostic
|
|
||||||
credential types into this field would blur the distinction between targeting a
|
|
||||||
cloud provider and using an open standard. Additionally, the SPIFFE credential
|
|
||||||
types do not require a `ServiceAccount` at all, which is fundamentally
|
|
||||||
different from how `.spec.provider` operates today.
|
|
||||||
|
|
||||||
#### Using an External SPIFFE Runtime (SPIRE)
|
|
||||||
|
|
||||||
Instead of issuing SPIFFE SVIDs directly, we could require users to deploy a
|
|
||||||
full SPIRE agent and have the Flux controllers obtain SVIDs through the SPIFFE
|
|
||||||
Workload API or Delegated Identity API. However, the standard
|
|
||||||
[Workload API](https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Workload_API.md)
|
|
||||||
only returns the identity assigned to the calling workload — it does not allow
|
|
||||||
the caller to request a specific SPIFFE ID. SPIRE's
|
|
||||||
[Delegated Identity API](https://spiffe.io/docs/latest/deploying/spire_agent/#delegated-identity-api)
|
|
||||||
does allow a trusted delegate (like a Flux controller) to obtain SVIDs on
|
|
||||||
behalf of other workloads, but those identities must still match pre-registered
|
|
||||||
entries on the SPIRE Server. This means a cluster administrator would need to
|
|
||||||
pre-register a SPIRE entry for every Flux object, which would be a significant
|
|
||||||
operational burden. Beyond this, deploying a full SPIRE infrastructure solely
|
|
||||||
for Flux authentication is a heavy dependency that many users would not want.
|
|
||||||
Our approach of issuing SVIDs directly from a provided private key is simpler
|
|
||||||
and self-contained, while still producing standard SPIFFE SVIDs that any
|
|
||||||
SPIFFE-aware service can verify.
|
|
||||||
|
|
||||||
## Design Details
|
|
||||||
|
|
||||||
### API Changes
|
|
||||||
|
|
||||||
For the `OCIRepository` API, we introduce the following new fields:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Credential specifies the configuration for vendor-agnostic short-lived
|
|
||||||
// credentials.
|
|
||||||
type Credential struct {
|
|
||||||
// Type specifies the type of credential to use for authentication.
|
|
||||||
// +required
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// Audiences specifies the audiences for the issued JWT when Type is
|
|
||||||
// ServiceAccountToken or SpiffeJWT. Defaults to .spec.url for
|
|
||||||
// OCIRepository and .spec.image for ImageRepository.
|
|
||||||
// +optional
|
|
||||||
Audiences []string `json:"audiences,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type OCIRepositorySpec struct {
|
|
||||||
// ... existing fields ...
|
|
||||||
|
|
||||||
// Credential specifies the vendor-agnostic short-lived credential
|
|
||||||
// configuration for authentication. Mutually exclusive with using
|
|
||||||
// .spec.provider for cloud-provider workload identity and with
|
|
||||||
// .spec.secretRef.
|
|
||||||
// +optional
|
|
||||||
Credential *Credential `json:"credential,omitempty"`
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Equivalent fields are introduced for the `ImageRepository` API.
|
|
||||||
|
|
||||||
### Validation Rules
|
|
||||||
|
|
||||||
- `.spec.credential` is mutually exclusive with `.spec.provider` when the
|
|
||||||
provider is set to anything other than `generic`.
|
|
||||||
- `.spec.credential` is mutually exclusive with `.spec.secretRef`.
|
|
||||||
- `.spec.credential.type` is required when `.spec.credential` is specified.
|
|
||||||
- `.spec.credential.audiences` is optional. When not specified and
|
|
||||||
`.spec.credential.type` is `ServiceAccountToken` or `SpiffeJWT`, the
|
|
||||||
audience defaults to `.spec.url` for `OCIRepository` and `.spec.image`
|
|
||||||
for `ImageRepository`.
|
|
||||||
- When `.spec.credential.type` is `SpiffeJWT`, the controller flags
|
|
||||||
`--spiffe-trust-domain`, `--spiffe-issuer` and `--spiffe-secret-name` must
|
|
||||||
be set, otherwise a terminal error is returned.
|
|
||||||
- When `.spec.credential.type` is `SpiffeCertificate`, the controller flags
|
|
||||||
`--spiffe-trust-domain` and `--spiffe-secret-name` must be set, otherwise a
|
|
||||||
terminal error is returned.
|
|
||||||
- When `.spec.credential.type` is `ServiceAccountToken`,
|
|
||||||
`.spec.serviceAccountName` is optional. If not set, the controller's own
|
|
||||||
`ServiceAccount` is used. Using `.spec.serviceAccountName` requires the
|
|
||||||
`ObjectLevelWorkloadIdentity` feature gate (introduced in RFC-0010) to be
|
|
||||||
enabled. In multi-tenancy lockdown scenarios, the
|
|
||||||
`--default-service-account` controller flag can be used to force a default
|
|
||||||
`ServiceAccount` when `.spec.serviceAccountName` is not specified, preventing
|
|
||||||
the controller's own `ServiceAccount` from being used.
|
|
||||||
|
|
||||||
### Credential Issuance
|
|
||||||
|
|
||||||
#### `ServiceAccountToken`
|
|
||||||
|
|
||||||
The controller uses the Kubernetes `TokenRequest` API to issue a short-lived
|
|
||||||
token for the configured `ServiceAccount` (or the controller's own
|
|
||||||
`ServiceAccount` if none is configured). The token is issued with the audiences
|
|
||||||
specified in `.spec.credential.audiences`. The token is then used as a bearer token in the
|
|
||||||
`Authorization` header when authenticating with the third-party service (e.g. a
|
|
||||||
container registry).
|
|
||||||
|
|
||||||
This reuses the same `ServiceAccount` token creation logic already present in
|
|
||||||
the `github.com/fluxcd/pkg/auth` library from RFC-0010, but skips the cloud
|
|
||||||
provider token exchange step.
|
|
||||||
|
|
||||||
#### `SpiffeJWT`
|
|
||||||
|
|
||||||
The controller constructs a JWT with the following claims:
|
|
||||||
|
|
||||||
- `iss`: The value of `--spiffe-issuer`.
|
|
||||||
- `sub`: The SPIFFE ID in the format
|
|
||||||
`spiffe://<trust-domain>/<resource>/<namespace>/<name>`, where the
|
|
||||||
trust domain is the value of `--spiffe-trust-domain`.
|
|
||||||
- `aud`: The values from `.spec.credential.audiences`.
|
|
||||||
- `exp`: One hour from the current time.
|
|
||||||
- `nbf`: The current time.
|
|
||||||
- `iat`: The current time.
|
|
||||||
- `jti`: A unique token identifier.
|
|
||||||
|
|
||||||
The JWT is signed using the private key from the `Secret` referenced by
|
|
||||||
`--spiffe-secret-name`. The signing algorithm is determined by the key type
|
|
||||||
(e.g. RS256 for RSA, ES256 for EC P-256).
|
|
||||||
|
|
||||||
#### `SpiffeCertificate`
|
|
||||||
|
|
||||||
The controller generates a short-lived x509 certificate with:
|
|
||||||
|
|
||||||
- The SPIFFE ID in the SAN URI field.
|
|
||||||
- A validity period of one hour.
|
|
||||||
- Signed by the CA from the `Secret` referenced by `--spiffe-secret-name`.
|
|
||||||
|
|
||||||
The certificate and a freshly generated private key are used for mTLS
|
|
||||||
authentication with the third-party service.
|
|
||||||
|
|
||||||
### Integration with the `auth` Library
|
|
||||||
|
|
||||||
We propose extending the `github.com/fluxcd/pkg/auth` library to support
|
|
||||||
vendor-agnostic credentials alongside the existing cloud-provider workload
|
|
||||||
identity. This involves:
|
|
||||||
|
|
||||||
1. Renaming the existing `auth/generic` package to `auth/serviceaccounttoken`.
|
|
||||||
2. Introducing `auth/spiffejwt` for issuing SPIFFE SVID JWTs, using a JWT
|
|
||||||
library (e.g. `golang.org/x/oauth2/jws` or `github.com/go-jose/go-jose`)
|
|
||||||
and standard Go crypto libraries (`crypto/rsa`, `crypto/ecdsa`) for signing.
|
|
||||||
3. Introducing `auth/spiffecertificate` for issuing SPIFFE SVID x509
|
|
||||||
certificates, using standard Go crypto libraries (`crypto/x509`,
|
|
||||||
`crypto/rsa`, `crypto/ecdsa`, `encoding/pem`) for certificate generation
|
|
||||||
and signing.
|
|
||||||
|
|
||||||
### CLI Support
|
|
||||||
|
|
||||||
The `flux push artifact` command (and related commands: `list`, `pull`, `tag`,
|
|
||||||
`diff`) will support the following credential types via the `--creds` flag:
|
|
||||||
|
|
||||||
#### `ServiceAccountToken`
|
|
||||||
|
|
||||||
Two modes are supported:
|
|
||||||
|
|
||||||
- **Token creation via `TokenRequest` API**: The CLI creates a short-lived
|
|
||||||
`ServiceAccount` token using the Kubernetes API. This mode works both inside
|
|
||||||
a pod (e.g. in a CI/CD pipeline running in-cluster) and locally with a
|
|
||||||
kubeconfig.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
flux push artifact --creds=ServiceAccountToken \
|
|
||||||
--audiences=aud1,aud2 \
|
|
||||||
--sa-name=my-sa
|
|
||||||
```
|
|
||||||
|
|
||||||
If `--sa-name` is not specified and the CLI is running inside a pod, it
|
|
||||||
reads the mounted `ServiceAccount` token file to determine the
|
|
||||||
`ServiceAccount` name. The `auth` library already has logic for finding
|
|
||||||
the current `ServiceAccount` when running inside a pod (used for issuing
|
|
||||||
controller-level tokens), so this can be reused by the CLI. If `--audiences`
|
|
||||||
is not specified, it defaults to the artifact URL. Note that this mode
|
|
||||||
requires the `create` verb on the `serviceaccounts/token` subresource for
|
|
||||||
the target `ServiceAccount`.
|
|
||||||
|
|
||||||
- **Pre-existing token file**: The CLI reads a `ServiceAccount` token from a
|
|
||||||
file. This mode is useful when the token has already been obtained through
|
|
||||||
other means, e.g. a
|
|
||||||
[projected volume](https://kubernetes.io/docs/concepts/storage/projected-volumes/#serviceaccounttoken).
|
|
||||||
|
|
||||||
```shell
|
|
||||||
flux push artifact --creds=ServiceAccountToken \
|
|
||||||
--sa-token=/path/to/token
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `SpiffeJWT` and `SpiffeCertificate`
|
|
||||||
|
|
||||||
In the controller, SPIFFE SVIDs are minted directly by the controller with
|
|
||||||
identities tied to Flux objects. In the CLI, there is no Flux object, and
|
|
||||||
providing the private signing key to the CLI would undermine the security model.
|
|
||||||
Instead, the CLI integrates with SPIRE via the
|
|
||||||
[SPIFFE Workload API](https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Workload_API.md)
|
|
||||||
using the [`go-spiffe`](https://github.com/spiffe/go-spiffe) library. In this
|
|
||||||
model, SPIRE assigns the identity to the calling workload (e.g. a CI runner
|
|
||||||
pod) based on its registration entries — the caller does not choose the SPIFFE
|
|
||||||
ID. These are complementary identity models: the controller mints SVIDs for
|
|
||||||
Flux objects, while the CLI relies on SPIRE to attest the workload running the
|
|
||||||
CLI.
|
|
||||||
|
|
||||||
For JWT SVIDs, the CLI calls `workloadapi.FetchJWTSVID()` with the specified
|
|
||||||
audiences:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
flux push artifact --creds=SpiffeJWT \
|
|
||||||
--audiences=aud1,aud2
|
|
||||||
```
|
|
||||||
|
|
||||||
If `--audiences` is not specified, it defaults to the artifact URL.
|
|
||||||
|
|
||||||
For x509 SVIDs, the CLI calls `workloadapi.FetchX509SVID()` and uses the
|
|
||||||
returned certificate and private key for mTLS client authentication:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
flux push artifact --creds=SpiffeCertificate
|
|
||||||
```
|
|
||||||
|
|
||||||
Both communicate with the SPIRE Agent via a Unix domain socket configured
|
|
||||||
through the `SPIFFE_ENDPOINT_SOCKET` environment variable.
|
|
||||||
|
|
||||||
Note that adding `github.com/spiffe/go-spiffe/v2` as a dependency to the CLI
|
|
||||||
binary pulls in gRPC (for the Workload API socket communication), which has a
|
|
||||||
non-trivial impact on binary size.
|
|
||||||
|
|
||||||
#### `GitHubOIDCToken`
|
|
||||||
|
|
||||||
As an exception to the "vendor-agnostic" scope of this RFC, the CLI will also
|
|
||||||
support GitHub Actions OIDC tokens. This is motivated by the fact that GitHub
|
|
||||||
Actions is a widely used CI/CD platform and its OIDC token API provides a
|
|
||||||
convenient way to obtain short-lived tokens without managing secrets. The CLI
|
|
||||||
obtains the token from the
|
|
||||||
[GitHub Actions OIDC Token API](https://docs.github.com/en/actions/reference/security/oidc#methods-for-requesting-the-oidc-token).
|
|
||||||
|
|
||||||
```shell
|
|
||||||
flux push artifact --creds=GitHubOIDCToken \
|
|
||||||
--audiences=aud1,aud2
|
|
||||||
```
|
|
||||||
|
|
||||||
If `--audiences` is not specified, it defaults to the artifact URL.
|
|
||||||
|
|
||||||
### Cache Considerations
|
|
||||||
|
|
||||||
The existing token cache from RFC-0010 can be reused. Following the same
|
|
||||||
principle established there, any new fields that interfere with the
|
|
||||||
creation of the credential will be included in the cache key.
|
|
||||||
|
|
||||||
### Security Considerations
|
|
||||||
|
|
||||||
- **Private key protection**: The `Secret` referenced by
|
|
||||||
`--spiffe-secret-name` contains sensitive cryptographic material. It must be
|
|
||||||
protected with appropriate RBAC and ideally managed through a secrets
|
|
||||||
management solution. The controller should only have read access to this
|
|
||||||
`Secret`.
|
|
||||||
- **Short-lived credentials**: All credential types produce short-lived tokens
|
|
||||||
or certificates (with a validity of one hour), limiting the blast radius if a
|
|
||||||
credential is leaked.
|
|
||||||
- **SPIFFE ID namespacing**: The SPIFFE ID includes the namespace and object
|
|
||||||
resource/name, providing natural multi-tenant isolation. A tenant's Flux
|
|
||||||
objects will always have SPIFFE IDs scoped to their namespace.
|
|
||||||
- **SPIFFE ID uniqueness**: The SPIFFE ID encodes the resource type, namespace
|
|
||||||
and name of the Flux object, which are unique within a cluster. This
|
|
||||||
guarantees that no two objects can have the same SPIFFE identity, preventing
|
|
||||||
one object from impersonating another (which is otherwise possible if using
|
|
||||||
a `ServiceAccount`).
|
|
||||||
- **Trust boundary**: When using `ServiceAccountToken`, the trust boundary is
|
|
||||||
the same as RFC-0010 (Kubernetes `ServiceAccount` token issuer). When using
|
|
||||||
SPIFFE credentials, the trust boundary extends to whoever has access to the
|
|
||||||
private key referenced by `--spiffe-secret-name`. This key should be
|
|
||||||
treated with the same level of care as the Kubernetes CA key.
|
|
||||||
|
|
||||||
### Proof of Concept
|
|
||||||
|
|
||||||
A proof of concept for the `ServiceAccountToken` credential type was tested
|
|
||||||
end-to-end and validated with two CNCF container registry projects:
|
|
||||||
[Harbor](https://goharbor.io/) and [Zot](https://zotregistry.dev/).
|
|
||||||
|
|
||||||
## Implementation History
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Major milestones in the lifecycle of the RFC such as:
|
|
||||||
- The first Flux release where an initial version of the RFC was available.
|
|
||||||
- The version of Flux where the RFC graduated to general availability.
|
|
||||||
- The version of Flux where the RFC was retired or superseded.
|
|
||||||
-->
|
|
||||||
@@ -88,6 +88,7 @@ metadata:
|
|||||||
log.Printf("failed to delete resources in '%s' namespace: %s", testID, err)
|
log.Printf("failed to delete resources in '%s' namespace: %s", testID, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Cleanup(func() { dumpDiagnostics(t, ctx, testID) })
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
err := verifyGitAndKustomization(ctx, testEnv, testID, testID)
|
err := verifyGitAndKustomization(ctx, testEnv, testID, testID)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import (
|
|||||||
func TestFluxInstallation(t *testing.T) {
|
func TestFluxInstallation(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
t.Cleanup(func() { dumpDiagnostics(t, ctx, "flux-system") })
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
err := verifyGitAndKustomization(ctx, testEnv.Client, "flux-system", "flux-system")
|
err := verifyGitAndKustomization(ctx, testEnv.Client, "flux-system", "flux-system")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -114,6 +115,7 @@ metadata:
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
ctx := context.TODO()
|
||||||
ref := &sourcev1.GitRepositoryRef{
|
ref := &sourcev1.GitRepositoryRef{
|
||||||
Branch: branchName,
|
Branch: branchName,
|
||||||
}
|
}
|
||||||
@@ -143,6 +145,7 @@ metadata:
|
|||||||
t.Logf("failed to delete resources in '%s' namespace: %s", tt.name, err)
|
t.Logf("failed to delete resources in '%s' namespace: %s", tt.name, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Cleanup(func() { dumpDiagnostics(t, ctx, testID) })
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
err := verifyGitAndKustomization(ctx, testEnv.Client, testID, testID)
|
err := verifyGitAndKustomization(ctx, testEnv.Client, testID, testID)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module github.com/fluxcd/flux2/tests/integration
|
module github.com/fluxcd/flux2/tests/integration
|
||||||
|
|
||||||
go 1.25.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/pubsub v1.50.1
|
cloud.google.com/go/pubsub v1.50.1
|
||||||
@@ -11,13 +11,13 @@ require (
|
|||||||
github.com/fluxcd/image-reflector-controller/api v1.0.4
|
github.com/fluxcd/image-reflector-controller/api v1.0.4
|
||||||
github.com/fluxcd/kustomize-controller/api v1.7.3
|
github.com/fluxcd/kustomize-controller/api v1.7.3
|
||||||
github.com/fluxcd/notification-controller/api v1.7.5
|
github.com/fluxcd/notification-controller/api v1.7.5
|
||||||
github.com/fluxcd/pkg/apis/event v0.22.0
|
github.com/fluxcd/pkg/apis/event v0.24.0
|
||||||
github.com/fluxcd/pkg/apis/meta v1.25.0
|
github.com/fluxcd/pkg/apis/meta v1.25.0
|
||||||
github.com/fluxcd/pkg/git v0.41.0
|
github.com/fluxcd/pkg/git v0.43.0
|
||||||
github.com/fluxcd/pkg/runtime v0.96.0
|
github.com/fluxcd/pkg/runtime v0.100.1
|
||||||
github.com/fluxcd/source-controller/api v1.7.4
|
github.com/fluxcd/source-controller/api v1.7.4
|
||||||
github.com/fluxcd/test-infra/tftestenv v0.0.0-20250626232827-e0ca9c3f8d7b
|
github.com/fluxcd/test-infra/tftestenv v0.0.0-20250626232827-e0ca9c3f8d7b
|
||||||
github.com/go-git/go-git/v5 v5.16.4
|
github.com/go-git/go-git/v5 v5.16.5
|
||||||
github.com/google/go-containerregistry v0.20.7
|
github.com/google/go-containerregistry v0.20.7
|
||||||
github.com/hashicorp/terraform-exec v0.24.0
|
github.com/hashicorp/terraform-exec v0.24.0
|
||||||
github.com/hashicorp/terraform-json v0.27.2
|
github.com/hashicorp/terraform-json v0.27.2
|
||||||
@@ -27,7 +27,7 @@ require (
|
|||||||
k8s.io/api v0.35.0
|
k8s.io/api v0.35.0
|
||||||
k8s.io/apimachinery v0.35.0
|
k8s.io/apimachinery v0.35.0
|
||||||
k8s.io/client-go v0.35.0
|
k8s.io/client-go v0.35.0
|
||||||
sigs.k8s.io/controller-runtime v0.23.0
|
sigs.k8s.io/controller-runtime v0.23.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -149,6 +149,6 @@ require (
|
|||||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
|
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // 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/v6 v6.3.0 // indirect
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
|
||||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -136,18 +136,18 @@ github.com/fluxcd/notification-controller/api v1.7.5 h1:6CO5bKyjodiK9exQFOdBcz0X
|
|||||||
github.com/fluxcd/notification-controller/api v1.7.5/go.mod h1:IciwSg8Q0pVtdbsyDyEXx/MxBKWeagxAazpm64C8oCE=
|
github.com/fluxcd/notification-controller/api v1.7.5/go.mod h1:IciwSg8Q0pVtdbsyDyEXx/MxBKWeagxAazpm64C8oCE=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA=
|
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/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
|
||||||
github.com/fluxcd/pkg/apis/event v0.22.0 h1:nCW0TnneMnscSnj9NlaSKcvyC+436MbY1GyKn/4YnII=
|
github.com/fluxcd/pkg/apis/event v0.24.0 h1:WVPf0FrJ5JExRDDGoo4W0jZgHZt0n4E48/e8b3TSmkA=
|
||||||
github.com/fluxcd/pkg/apis/event v0.22.0/go.mod h1:Hoi4DejaNKVahGkRXqGBjT9h1aKmhc7RCYcsgoTieqc=
|
github.com/fluxcd/pkg/apis/event v0.24.0/go.mod h1:Hoi4DejaNKVahGkRXqGBjT9h1aKmhc7RCYcsgoTieqc=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.15.0 h1:p8wPIxdmn0vy0a664rsE9JKCfnliZz4HUsDcTy4ZOxA=
|
github.com/fluxcd/pkg/apis/kustomize v1.15.0 h1:p8wPIxdmn0vy0a664rsE9JKCfnliZz4HUsDcTy4ZOxA=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.15.0/go.mod h1:XWdsx8P15OiMaQIvmUjYWdmD3zAwhl5q9osl5iCqcOk=
|
github.com/fluxcd/pkg/apis/kustomize v1.15.0/go.mod h1:XWdsx8P15OiMaQIvmUjYWdmD3zAwhl5q9osl5iCqcOk=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.25.0 h1:fmZgMoe7yITGfhFqdOs7w2GOu3Y/2Vvz4+4p/eay3eA=
|
github.com/fluxcd/pkg/apis/meta v1.25.0 h1:fmZgMoe7yITGfhFqdOs7w2GOu3Y/2Vvz4+4p/eay3eA=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.25.0/go.mod h1:1D92RqAet0/n/cH5S0khBXweirHWkw9rCO0V4NCY6xc=
|
github.com/fluxcd/pkg/apis/meta v1.25.0/go.mod h1:1D92RqAet0/n/cH5S0khBXweirHWkw9rCO0V4NCY6xc=
|
||||||
github.com/fluxcd/pkg/git v0.41.0 h1:WvvIUFssFDKpRrptJjDf0B4mrUCwhesv1Txu3DzTsl8=
|
github.com/fluxcd/pkg/git v0.43.0 h1:11LKsTHw+yx3rcGSrSbkURcdc4huUv3FxQZhHIAMofc=
|
||||||
github.com/fluxcd/pkg/git v0.41.0/go.mod h1:iqR4eZEhd3gdRSkv+VDP3Qz9WCner3aZ5ClkOUe+3fc=
|
github.com/fluxcd/pkg/git v0.43.0/go.mod h1:cr9eoYLZHKP3NWgJhhJ8pBcllTpl2SbXVoifW37IyIQ=
|
||||||
github.com/fluxcd/pkg/gittestserver v0.24.0 h1:ZIksyENX8yPlB95GJGoUIT171o2oKFJvFSXu+4mEmzU=
|
github.com/fluxcd/pkg/gittestserver v0.25.0 h1:thnS0OOuU2mEA0PjByxrSxrvlvSwVxJSZY1me782Vq4=
|
||||||
github.com/fluxcd/pkg/gittestserver v0.24.0/go.mod h1:9l+gwEfqqe/WxiRvIrQxircgDcXUF3/tw/1Bie/XwJc=
|
github.com/fluxcd/pkg/gittestserver v0.25.0/go.mod h1:cQqa3cOdKdrIDUqV8SCYbIoNw4/a8frJRGofBLv7sWw=
|
||||||
github.com/fluxcd/pkg/runtime v0.96.0 h1:sF4ic8131BwbOE+T2pkiXlkr2gCaxAho500zlZJJLck=
|
github.com/fluxcd/pkg/runtime v0.100.1 h1:UiPmgY8Yv7UF06MT5T8AG9uDGNszm75/DQtK6JEhnrM=
|
||||||
github.com/fluxcd/pkg/runtime v0.96.0/go.mod h1:FyjNMFNAERkCsF/muTWJYU9MZOsq/m4Sc4aQk/EgQ9E=
|
github.com/fluxcd/pkg/runtime v0.100.1/go.mod h1:SctSsHvFwUfiOVP1zirP6mo7I8wQtXeWVl2lNQWal88=
|
||||||
github.com/fluxcd/pkg/ssh v0.24.0 h1:hrPlxs0hhXf32DRqs68VbsXs0XfQMphyRVIk0rYYJa4=
|
github.com/fluxcd/pkg/ssh v0.24.0 h1:hrPlxs0hhXf32DRqs68VbsXs0XfQMphyRVIk0rYYJa4=
|
||||||
github.com/fluxcd/pkg/ssh v0.24.0/go.mod h1:xWammEqalrpurpcMiixJRXtynRQtBEoqheyU5F/vWrg=
|
github.com/fluxcd/pkg/ssh v0.24.0/go.mod h1:xWammEqalrpurpcMiixJRXtynRQtBEoqheyU5F/vWrg=
|
||||||
github.com/fluxcd/pkg/version v0.12.0 h1:MGbdbNf2D5wazMqAkNPn+Lh5j+oY0gxQJFTGyet5Hfc=
|
github.com/fluxcd/pkg/version v0.12.0 h1:MGbdbNf2D5wazMqAkNPn+Lh5j+oY0gxQJFTGyet5Hfc=
|
||||||
@@ -168,8 +168,8 @@ github.com/go-git/go-billy/v5 v5.7.0 h1:83lBUJhGWhYp0ngzCMSgllhUSuoHP1iEWYjsPl9n
|
|||||||
github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E=
|
github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||||
github.com/go-git/go-git/v5 v5.16.4 h1:7ajIEZHZJULcyJebDLo99bGgS0jRrOxzZG4uCk2Yb2Y=
|
github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
|
||||||
github.com/go-git/go-git/v5 v5.16.4/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
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/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
@@ -534,13 +534,13 @@ k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZ
|
|||||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
|
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
|
||||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
sigs.k8s.io/controller-runtime v0.23.0 h1:Ubi7klJWiwEWqDY+odSVZiFA0aDSevOCXpa38yCSYu8=
|
sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE=
|
||||||
sigs.k8s.io/controller-runtime v0.23.0/go.mod h1:DBOIr9NsprUqCZ1ZhsuJ0wAnQSIxY/C6VjZbmLgw0j0=
|
sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
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/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 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/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs=
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ spec:
|
|||||||
t.Logf("failed to delete resources in '%s' namespace: %s", testID, err)
|
t.Logf("failed to delete resources in '%s' namespace: %s", testID, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Cleanup(func() { dumpDiagnostics(t, ctx, testID) })
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
err := verifyGitAndKustomization(ctx, testEnv.Client, testID, testID)
|
err := verifyGitAndKustomization(ctx, testEnv.Client, testID, testID)
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ metadata:
|
|||||||
t.Logf("failed to delete resources in '%s' namespace: %s", testID, err)
|
t.Logf("failed to delete resources in '%s' namespace: %s", testID, err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Cleanup(func() { dumpDiagnostics(t, ctx, testID) })
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
err := verifyGitAndKustomization(ctx, testEnv, testID, testID)
|
err := verifyGitAndKustomization(ctx, testEnv, testID, testID)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package integration
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ func TestOCIHelmRelease(t *testing.T) {
|
|||||||
}
|
}
|
||||||
g.Expect(testEnv.Create(ctx, &namespace)).To(Succeed())
|
g.Expect(testEnv.Create(ctx, &namespace)).To(Succeed())
|
||||||
defer testEnv.Delete(ctx, &namespace)
|
defer testEnv.Delete(ctx, &namespace)
|
||||||
|
t.Cleanup(func() { dumpDiagnostics(t, ctx, testID) })
|
||||||
|
|
||||||
repoURL := fmt.Sprintf("%s/charts/podinfo", cfg.testRegistry)
|
repoURL := fmt.Sprintf("%s/charts/podinfo", cfg.testRegistry)
|
||||||
err := pushImagesFromURL(repoURL, "ghcr.io/stefanprodan/charts/podinfo:6.2.0", []string{"6.2.0"})
|
err := pushImagesFromURL(repoURL, "ghcr.io/stefanprodan/charts/podinfo:6.2.0", []string{"6.2.0"})
|
||||||
@@ -97,23 +99,31 @@ func TestOCIHelmRelease(t *testing.T) {
|
|||||||
Namespace: helmRelease.Namespace,
|
Namespace: helmRelease.Namespace,
|
||||||
}
|
}
|
||||||
if err := testEnv.Get(ctx, nn, chart); err != nil {
|
if err := testEnv.Get(ctx, nn, chart); err != nil {
|
||||||
t.Logf("error getting helm chart %s\n", err.Error())
|
t.Logf("error getting helm chart: %s", err.Error())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if err := checkReadyCondition(chart); err != nil {
|
if err := checkReadyCondition(chart); err != nil {
|
||||||
t.Log(err)
|
t.Logf("HelmChart not ready: %s", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := &helmv2.HelmRelease{}
|
obj := &helmv2.HelmRelease{}
|
||||||
nn = types.NamespacedName{Name: helmRelease.Name, Namespace: helmRelease.Namespace}
|
nn = types.NamespacedName{Name: helmRelease.Name, Namespace: helmRelease.Namespace}
|
||||||
if err := testEnv.Get(ctx, nn, obj); err != nil {
|
if err := testEnv.Get(ctx, nn, obj); err != nil {
|
||||||
t.Logf("error getting helm release %s\n", err.Error())
|
t.Logf("error getting helm release: %s", err.Error())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkReadyCondition(obj); err != nil {
|
if err := checkReadyCondition(obj); err != nil {
|
||||||
t.Log(err)
|
// Log all HelmRelease conditions for full picture.
|
||||||
|
var condSummary []string
|
||||||
|
for _, c := range obj.Status.Conditions {
|
||||||
|
condSummary = append(condSummary, fmt.Sprintf("%s=%s (%s)", c.Type, c.Status, c.Message))
|
||||||
|
}
|
||||||
|
t.Logf("HelmRelease not ready: conditions=[%s]", strings.Join(condSummary, "; "))
|
||||||
|
|
||||||
|
// Log pod states in the release namespace.
|
||||||
|
logNamespacePods(t, ctx, testID)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ stringData:
|
|||||||
log.Printf("failed to delete resources in '%s' namespace", testID)
|
log.Printf("failed to delete resources in '%s' namespace", testID)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Cleanup(func() { dumpDiagnostics(t, ctx, testID) })
|
||||||
|
|
||||||
if cfg.sopsSecretData != nil {
|
if cfg.sopsSecretData != nil {
|
||||||
secret := corev1.Secret{
|
secret := corev1.Secret{
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
extgogit "github.com/go-git/go-git/v5"
|
extgogit "github.com/go-git/go-git/v5"
|
||||||
@@ -37,6 +38,9 @@ import (
|
|||||||
kerrors "k8s.io/apimachinery/pkg/util/errors"
|
kerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
helmv2 "github.com/fluxcd/helm-controller/api/v2"
|
||||||
|
automationv1 "github.com/fluxcd/image-automation-controller/api/v1"
|
||||||
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1"
|
||||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
"github.com/fluxcd/pkg/git"
|
"github.com/fluxcd/pkg/git"
|
||||||
@@ -411,10 +415,164 @@ func checkReadyCondition(from conditions.Getter) error {
|
|||||||
if conditions.IsReady(from) {
|
if conditions.IsReady(from) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
errMsg := fmt.Sprintf("object not ready")
|
errMsg := "object not ready"
|
||||||
readyMsg := conditions.GetMessage(from, meta.ReadyCondition)
|
readyMsg := conditions.GetMessage(from, meta.ReadyCondition)
|
||||||
if readyMsg != "" {
|
if readyMsg != "" {
|
||||||
errMsg += ": " + readyMsg
|
errMsg += ": " + readyMsg
|
||||||
}
|
}
|
||||||
return errors.New(errMsg)
|
return errors.New(errMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dumpDiagnostics prints Flux object states and controller logs when a test
|
||||||
|
// has failed. It should be registered via t.Cleanup so that it runs after the
|
||||||
|
// test body completes.
|
||||||
|
func dumpDiagnostics(t *testing.T, ctx context.Context, namespace string) {
|
||||||
|
t.Helper()
|
||||||
|
if !t.Failed() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("=== Diagnostics dump (test failed) ===")
|
||||||
|
dumpFluxObjects(t, ctx, namespace)
|
||||||
|
dumpControllerLogs(t, ctx)
|
||||||
|
t.Log("=== End diagnostics dump ===")
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpFluxObjects lists Flux custom resources in the given namespace and prints
|
||||||
|
// their status conditions.
|
||||||
|
func dumpFluxObjects(t *testing.T, ctx context.Context, namespace string) {
|
||||||
|
t.Helper()
|
||||||
|
listOpts := &client.ListOptions{Namespace: namespace}
|
||||||
|
|
||||||
|
gitRepos := &sourcev1.GitRepositoryList{}
|
||||||
|
if err := testEnv.List(ctx, gitRepos, listOpts); err == nil {
|
||||||
|
for _, r := range gitRepos.Items {
|
||||||
|
logObjectStatus(t, "GitRepository", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
helmRepos := &sourcev1.HelmRepositoryList{}
|
||||||
|
if err := testEnv.List(ctx, helmRepos, listOpts); err == nil {
|
||||||
|
for _, r := range helmRepos.Items {
|
||||||
|
logObjectStatus(t, "HelmRepository", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
helmCharts := &sourcev1.HelmChartList{}
|
||||||
|
if err := testEnv.List(ctx, helmCharts, listOpts); err == nil {
|
||||||
|
for _, r := range helmCharts.Items {
|
||||||
|
logObjectStatus(t, "HelmChart", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kustomizations := &kustomizev1.KustomizationList{}
|
||||||
|
if err := testEnv.List(ctx, kustomizations, listOpts); err == nil {
|
||||||
|
for _, r := range kustomizations.Items {
|
||||||
|
logObjectStatus(t, "Kustomization", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
helmReleases := &helmv2.HelmReleaseList{}
|
||||||
|
if err := testEnv.List(ctx, helmReleases, listOpts); err == nil {
|
||||||
|
for _, r := range helmReleases.Items {
|
||||||
|
logObjectStatus(t, "HelmRelease", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imageRepos := &reflectorv1.ImageRepositoryList{}
|
||||||
|
if err := testEnv.List(ctx, imageRepos, listOpts); err == nil {
|
||||||
|
for _, r := range imageRepos.Items {
|
||||||
|
logObjectStatus(t, "ImageRepository", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imagePolicies := &reflectorv1.ImagePolicyList{}
|
||||||
|
if err := testEnv.List(ctx, imagePolicies, listOpts); err == nil {
|
||||||
|
for _, r := range imagePolicies.Items {
|
||||||
|
logObjectStatus(t, "ImagePolicy", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imageAutomations := &automationv1.ImageUpdateAutomationList{}
|
||||||
|
if err := testEnv.List(ctx, imageAutomations, listOpts); err == nil {
|
||||||
|
for _, r := range imageAutomations.Items {
|
||||||
|
logObjectStatus(t, "ImageUpdateAutomation", r.Name, r.Namespace, r.Status.Conditions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// logObjectStatus prints the status conditions of a Flux object.
|
||||||
|
func logObjectStatus(t *testing.T, kind, name, namespace string, conditions []metav1.Condition) {
|
||||||
|
t.Helper()
|
||||||
|
t.Logf(" %s/%s (ns: %s):", kind, name, namespace)
|
||||||
|
for _, c := range conditions {
|
||||||
|
t.Logf(" %s: %s — %s (since %s)", c.Type, c.Status, c.Message, c.LastTransitionTime.Format(time.RFC3339))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpControllerLogs prints the logs of all Flux controller pods in the
|
||||||
|
// flux-system namespace.
|
||||||
|
func dumpControllerLogs(t *testing.T, ctx context.Context) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
podList, err := testEnv.ClientGo.CoreV1().Pods("flux-system").List(ctx, metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("failed to list flux-system pods: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pod := range podList.Items {
|
||||||
|
logs, err := testEnv.ClientGo.
|
||||||
|
CoreV1().
|
||||||
|
Pods(pod.Namespace).
|
||||||
|
GetLogs(pod.Name, &corev1.PodLogOptions{}).
|
||||||
|
DoRaw(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("failed to get logs for pod %s: %v", pod.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t.Logf("=== Logs for pod %s ===\n%s", pod.Name, string(logs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// logNamespacePods logs the state of all pods in the given namespace,
|
||||||
|
// including container statuses and recent events. Useful for understanding
|
||||||
|
// why a Helm install is stuck.
|
||||||
|
func logNamespacePods(t *testing.T, ctx context.Context, namespace string) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
podList := &corev1.PodList{}
|
||||||
|
if err := testEnv.List(ctx, podList, &client.ListOptions{Namespace: namespace}); err != nil {
|
||||||
|
t.Logf(" failed to list pods in %s: %v", namespace, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(podList.Items) == 0 {
|
||||||
|
t.Logf(" no pods in namespace %s", namespace)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, pod := range podList.Items {
|
||||||
|
t.Logf(" pod %s: phase=%s", pod.Name, pod.Status.Phase)
|
||||||
|
for _, cs := range pod.Status.ContainerStatuses {
|
||||||
|
if cs.State.Waiting != nil {
|
||||||
|
t.Logf(" container %s: waiting — %s: %s", cs.Name, cs.State.Waiting.Reason, cs.State.Waiting.Message)
|
||||||
|
} else if cs.State.Terminated != nil {
|
||||||
|
t.Logf(" container %s: terminated — %s (exit %d)", cs.Name, cs.State.Terminated.Reason, cs.State.Terminated.ExitCode)
|
||||||
|
} else if cs.State.Running != nil {
|
||||||
|
t.Logf(" container %s: running (ready=%v)", cs.Name, cs.Ready)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log recent events in the namespace for scheduling/pull failures.
|
||||||
|
events, err := testEnv.ClientGo.CoreV1().Events(namespace).List(ctx, metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Logf(" failed to list events in %s: %v", namespace, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(events.Items) > 0 {
|
||||||
|
t.Logf(" events in namespace %s:", namespace)
|
||||||
|
for _, e := range events.Items {
|
||||||
|
t.Logf(" %s %s/%s: %s — %s", e.Type, e.InvolvedObject.Kind, e.InvolvedObject.Name, e.Reason, e.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user