Compare commits
58 Commits
Author | SHA1 | Date |
---|---|---|
|
0c36aa0904 | |
|
5329f56881 | |
|
049a805992 | |
|
3d6179cc99 | |
|
2e1ef03389 | |
|
afdc58cd48 | |
|
9c41b0649d | |
|
493fbfee62 | |
|
f83bc52441 | |
|
4dc270e06c | |
|
ca604f3389 | |
|
cf3e7b7204 | |
|
e722bbbf50 | |
|
f133b50872 | |
|
6b2e5e8729 | |
|
0f1d6864e9 | |
|
2e9eb7c9fd | |
|
7a399d5ec7 | |
|
177f19c460 | |
|
57eaa2ea00 | |
|
44cddcb72d | |
|
eacc2a05a8 | |
|
e7aaaf2a3e | |
|
c5f0efdced | |
|
aaad1e033e | |
|
c8b9d82b71 | |
|
60b8f86f49 | |
|
fd63b520d5 | |
|
d17e5d2514 | |
|
e0e6e22272 | |
|
c2754dd5de | |
|
5edcf5b394 | |
|
8ec3ec388d | |
|
0c48a16ede | |
|
c48ffbef1c | |
|
2dcec193bb | |
|
b4d23e756f | |
|
2fb1fa3890 | |
|
ba3c16aa45 | |
|
2fb1482f71 | |
|
52170876d5 | |
|
1476042b1e | |
|
f479c3e1f6 | |
|
bc4756a38f | |
|
5703d47395 | |
|
30275f2615 | |
|
a342d00602 | |
|
4623a38989 | |
|
124402b53a | |
|
8e90ab8008 | |
|
8c1d87ba6a | |
|
8479377cd7 | |
|
ebee7880e7 | |
|
9f784c5e9f | |
|
07837f603c | |
|
ee8981f35d | |
|
40a75725dd | |
|
f1cfd9f0c8 |
|
@ -5,7 +5,7 @@ updates:
|
||||||
directory: "/"
|
directory: "/"
|
||||||
labels: ["dependencies"]
|
labels: ["dependencies"]
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "monthly"
|
||||||
groups:
|
groups:
|
||||||
go-deps:
|
go-deps:
|
||||||
patterns:
|
patterns:
|
||||||
|
@ -31,4 +31,4 @@ updates:
|
||||||
patterns:
|
patterns:
|
||||||
- "*"
|
- "*"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "monthly"
|
||||||
|
|
|
@ -35,3 +35,6 @@
|
||||||
- name: backport:release/v1.5.x
|
- name: backport:release/v1.5.x
|
||||||
description: To be backported to release/v1.5.x
|
description: To be backported to release/v1.5.x
|
||||||
color: '#ffd700'
|
color: '#ffd700'
|
||||||
|
- name: backport:release/v1.6.x
|
||||||
|
description: To be backported to release/v1.6.x
|
||||||
|
color: '#ffd700'
|
||||||
|
|
|
@ -16,11 +16,11 @@ jobs:
|
||||||
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
|
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Create backport PRs
|
- name: Create backport PRs
|
||||||
uses: korthout/backport-action@436145e922f9561fc5ea157ff406f21af2d6b363 # v3.2.0
|
uses: korthout/backport-action@ca4972adce8039ff995e618f5fc02d1b7961f27a # v3.3.0
|
||||||
# xref: https://github.com/korthout/backport-action#inputs
|
# xref: https://github.com/korthout/backport-action#inputs
|
||||||
with:
|
with:
|
||||||
# Use token to allow workflows to be triggered for the created PR
|
# Use token to allow workflows to be triggered for the created PR
|
||||||
|
|
|
@ -12,11 +12,11 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.25.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
|
|
|
@ -15,14 +15,14 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup QEMU
|
- name: Setup QEMU
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||||
- name: Setup Docker Buildx
|
- name: Setup Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
- name: Cache Docker layers
|
- name: Cache Docker layers
|
||||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
path: /tmp/.buildx-cache
|
path: /tmp/.buildx-cache
|
||||||
|
@ -32,7 +32,7 @@ jobs:
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.25.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
|
|
|
@ -15,16 +15,16 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup QEMU
|
- name: Setup QEMU
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||||
- name: Setup Docker Buildx
|
- name: Setup Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
with:
|
with:
|
||||||
buildkitd-flags: "--debug"
|
buildkitd-flags: "--debug"
|
||||||
- name: Build multi-arch container image
|
- name: Build multi-arch container image
|
||||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
with:
|
with:
|
||||||
push: false
|
push: false
|
||||||
builder: ${{ steps.buildx.outputs.name }}
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
|
|
|
@ -29,7 +29,7 @@ jobs:
|
||||||
packages: write # for pushing and signing container images.
|
packages: write # for pushing and signing container images.
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Kustomize
|
- name: Setup Kustomize
|
||||||
uses: fluxcd/pkg/actions/kustomize@main
|
uses: fluxcd/pkg/actions/kustomize@main
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
|
@ -45,21 +45,21 @@ jobs:
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||||
- name: Setup Docker Buildx
|
- name: Setup Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: fluxcdbot
|
username: fluxcdbot
|
||||||
password: ${{ secrets.GHCR_TOKEN }}
|
password: ${{ secrets.GHCR_TOKEN }}
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
|
||||||
with:
|
with:
|
||||||
username: fluxcdbot
|
username: fluxcdbot
|
||||||
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
||||||
- name: Generate images meta
|
- name: Generate images meta
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
fluxcd/${{ env.CONTROLLER }}
|
fluxcd/${{ env.CONTROLLER }}
|
||||||
|
@ -68,7 +68,7 @@ jobs:
|
||||||
type=raw,value=${{ steps.prep.outputs.VERSION }}
|
type=raw,value=${{ steps.prep.outputs.VERSION }}
|
||||||
- name: Publish images
|
- name: Publish images
|
||||||
id: build-push
|
id: build-push
|
||||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
with:
|
with:
|
||||||
sbom: true
|
sbom: true
|
||||||
provenance: true
|
provenance: true
|
||||||
|
@ -79,7 +79,7 @@ jobs:
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
- uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
|
- uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
|
||||||
- name: Sign images
|
- name: Sign images
|
||||||
env:
|
env:
|
||||||
COSIGN_EXPERIMENTAL: 1
|
COSIGN_EXPERIMENTAL: 1
|
||||||
|
@ -92,11 +92,11 @@ jobs:
|
||||||
mkdir -p config/release
|
mkdir -p config/release
|
||||||
kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml
|
kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml
|
||||||
kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml
|
kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml
|
||||||
- uses: anchore/sbom-action/download-syft@e11c554f704a0b820cbf8c51673f6945e0731532 # v0.20.0
|
- uses: anchore/sbom-action/download-syft@da167eac915b4e86f08b264dbdbc867b61be6f0c # v0.20.5
|
||||||
- name: Create release and SBOM
|
- name: Create release and SBOM
|
||||||
id: run-goreleaser
|
id: run-goreleaser
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
|
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
args: release --clean --skip=validate
|
args: release --clean --skip=validate
|
||||||
|
|
|
@ -18,7 +18,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Run FOSSA scan and upload build data
|
- name: Run FOSSA scan and upload build data
|
||||||
uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1
|
uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1
|
||||||
with:
|
with:
|
||||||
|
@ -31,22 +31,22 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.25.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
uses: github/codeql-action/init@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
||||||
with:
|
with:
|
||||||
languages: go
|
languages: go
|
||||||
# xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
# xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||||
# xref: https://codeql.github.com/codeql-query-help/go/
|
# xref: https://codeql.github.com/codeql-query-help/go/
|
||||||
queries: security-and-quality
|
queries: security-and-quality
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
uses: github/codeql-action/autobuild@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
uses: github/codeql-action/analyze@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
||||||
|
|
|
@ -17,7 +17,7 @@ jobs:
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
|
- uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
|
||||||
with:
|
with:
|
||||||
# Configuration file
|
# Configuration file
|
||||||
|
|
|
@ -19,6 +19,7 @@ config/release/
|
||||||
config/crd/bases/ocirepositories.yaml
|
config/crd/bases/ocirepositories.yaml
|
||||||
config/crd/bases/gitrepositories.yaml
|
config/crd/bases/gitrepositories.yaml
|
||||||
config/crd/bases/buckets.yaml
|
config/crd/bases/buckets.yaml
|
||||||
|
config/crd/bases/externalartifacts.yaml
|
||||||
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
|
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -2,6 +2,24 @@
|
||||||
|
|
||||||
All notable changes to this project are documented in this file.
|
All notable changes to this project are documented in this file.
|
||||||
|
|
||||||
|
## 1.6.1
|
||||||
|
|
||||||
|
**Release date:** 2025-07-08
|
||||||
|
|
||||||
|
This patch release fixes a bug introduced in v1.6.0
|
||||||
|
that causes SOPS decryption with US Government KMS
|
||||||
|
keys to fail with the error:
|
||||||
|
|
||||||
|
```
|
||||||
|
STS: AssumeRoleWithWebIdentity, https response error\n StatusCode: 0, RequestID: ,
|
||||||
|
request send failed, Post\n \"https://sts.arn.amazonaws.com/\": dial tcp:
|
||||||
|
lookupts.arn.amazonaws.com on 10.100.0.10:53: no such host
|
||||||
|
```
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Fix regression in STS endpoint for SOPS decryption with AWS KMS in US Gov partition
|
||||||
|
[#1478](https://github.com/fluxcd/kustomize-controller/pull/1478)
|
||||||
|
|
||||||
## 1.6.0
|
## 1.6.0
|
||||||
|
|
||||||
**Release date:** 2025-05-28
|
**Release date:** 2025-05-28
|
||||||
|
|
|
@ -16,7 +16,7 @@ There are a number of dependencies required to be able to run the controller and
|
||||||
## How to run the test suite
|
## How to run the test suite
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
* Go >= 1.24
|
* Go >= 1.25
|
||||||
|
|
||||||
You can run the test suite by simply doing
|
You can run the test suite by simply doing
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ARG GO_VERSION=1.24
|
ARG GO_VERSION=1.25
|
||||||
ARG XX_VERSION=1.6.1
|
ARG XX_VERSION=1.6.1
|
||||||
|
|
||||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||||
|
@ -30,7 +30,7 @@ COPY internal/ internal/
|
||||||
ENV CGO_ENABLED=0
|
ENV CGO_ENABLED=0
|
||||||
RUN xx-go build -trimpath -a -o kustomize-controller main.go
|
RUN xx-go build -trimpath -a -o kustomize-controller main.go
|
||||||
|
|
||||||
FROM alpine:3.21
|
FROM alpine:3.22
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
|
14
Makefile
14
Makefile
|
@ -38,13 +38,14 @@ ENVTEST_ARCH ?= amd64
|
||||||
GITREPO_CRD ?= config/crd/bases/gitrepositories.yaml
|
GITREPO_CRD ?= config/crd/bases/gitrepositories.yaml
|
||||||
BUCKET_CRD ?= config/crd/bases/buckets.yaml
|
BUCKET_CRD ?= config/crd/bases/buckets.yaml
|
||||||
OCIREPO_CRD ?= config/crd/bases/ocirepositories.yaml
|
OCIREPO_CRD ?= config/crd/bases/ocirepositories.yaml
|
||||||
|
EA_CRD ?= config/crd/bases/externalartifacts.yaml
|
||||||
|
|
||||||
# Keep a record of the version of the downloaded source CRDs. It is used to
|
# Keep a record of the version of the downloaded source CRDs. It is used to
|
||||||
# detect and download new CRDs when the SOURCE_VER changes.
|
# detect and download new CRDs when the SOURCE_VER changes.
|
||||||
SOURCE_CRD_VER=$(BUILD_DIR)/.src-crd-$(SOURCE_VER)
|
SOURCE_CRD_VER=$(BUILD_DIR)/.src-crd-$(SOURCE_VER)
|
||||||
|
|
||||||
# API (doc) generation utilities
|
# API (doc) generation utilities
|
||||||
CONTROLLER_GEN_VERSION ?= v0.16.1
|
CONTROLLER_GEN_VERSION ?= v0.19.0
|
||||||
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
|
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
|
||||||
|
|
||||||
all: manager
|
all: manager
|
||||||
|
@ -90,12 +91,15 @@ $(BUCKET_CRD):
|
||||||
$(OCIREPO_CRD):
|
$(OCIREPO_CRD):
|
||||||
curl -s https://raw.githubusercontent.com/fluxcd/source-controller/${SOURCE_VER}/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml -o $(OCIREPO_CRD)
|
curl -s https://raw.githubusercontent.com/fluxcd/source-controller/${SOURCE_VER}/config/crd/bases/source.toolkit.fluxcd.io_ocirepositories.yaml -o $(OCIREPO_CRD)
|
||||||
|
|
||||||
|
$(EA_CRD):
|
||||||
|
curl -s https://raw.githubusercontent.com/fluxcd/source-controller/${SOURCE_VER}/config/crd/bases/source.toolkit.fluxcd.io_externalartifacts.yaml -o $(EA_CRD)
|
||||||
|
|
||||||
# Download the CRDs the controller depends on
|
# Download the CRDs the controller depends on
|
||||||
download-crd-deps: $(SOURCE_CRD_VER) $(GITREPO_CRD) $(BUCKET_CRD) $(OCIREPO_CRD)
|
download-crd-deps: $(SOURCE_CRD_VER) $(GITREPO_CRD) $(BUCKET_CRD) $(OCIREPO_CRD) $(EA_CRD)
|
||||||
|
|
||||||
# Delete the downloaded CRD dependencies.
|
# Delete the downloaded CRD dependencies.
|
||||||
cleanup-crd-deps:
|
cleanup-crd-deps:
|
||||||
rm -f $(GITREPO_CRD) $(BUCKET_CRD) $(OCIREPO_CRD)
|
rm -f $(GITREPO_CRD) $(BUCKET_CRD) $(OCIREPO_CRD) $(EA_CRD)
|
||||||
|
|
||||||
# Install CRDs into a cluster
|
# Install CRDs into a cluster
|
||||||
install: manifests
|
install: manifests
|
||||||
|
@ -135,8 +139,8 @@ api-docs: gen-crd-api-reference-docs
|
||||||
|
|
||||||
# Run go mod tidy
|
# Run go mod tidy
|
||||||
tidy:
|
tidy:
|
||||||
cd api; rm -f go.sum; go mod tidy -compat=1.24
|
cd api; rm -f go.sum; go mod tidy -compat=1.25
|
||||||
rm -f go.sum; go mod tidy -compat=1.24
|
rm -f go.sum; go mod tidy -compat=1.25
|
||||||
|
|
||||||
# Run go fmt against code
|
# Run go fmt against code
|
||||||
fmt:
|
fmt:
|
||||||
|
|
32
api/go.mod
32
api/go.mod
|
@ -1,36 +1,32 @@
|
||||||
module github.com/fluxcd/kustomize-controller/api
|
module github.com/fluxcd/kustomize-controller/api
|
||||||
|
|
||||||
go 1.24.0
|
go 1.25.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.10.0
|
github.com/fluxcd/pkg/apis/kustomize v1.12.0
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0
|
github.com/fluxcd/pkg/apis/meta v1.20.0
|
||||||
k8s.io/apiextensions-apiserver v0.33.0
|
k8s.io/apiextensions-apiserver v0.34.0
|
||||||
k8s.io/apimachinery v0.33.0
|
k8s.io/apimachinery v0.34.0
|
||||||
sigs.k8s.io/controller-runtime v0.21.0
|
sigs.k8s.io/controller-runtime v0.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fix CVE-2022-28948
|
|
||||||
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||||
github.com/go-logr/logr v1.4.2 // indirect
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||||
github.com/spf13/pflag v1.0.6 // indirect
|
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
golang.org/x/net v0.40.0 // indirect
|
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||||
golang.org/x/text v0.25.0 // indirect
|
golang.org/x/net v0.43.0 // indirect
|
||||||
golang.org/x/tools v0.33.0 // indirect
|
golang.org/x/text v0.28.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect
|
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
||||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
65
api/go.sum
65
api/go.sum
|
@ -2,19 +2,18 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.10.0 h1:47EeSzkQvlQZdH92vHMe2lK2iR8aOSEJq95avw5idts=
|
github.com/fluxcd/pkg/apis/kustomize v1.12.0 h1:KvZN6xwgP/dNSeckL4a/Uv715XqiN1C3xS+jGcPejtE=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.10.0/go.mod h1:UsqMV4sqNa1Yg0pmTsdkHRJr7bafBOENIJoAN+3ezaQ=
|
github.com/fluxcd/pkg/apis/kustomize v1.12.0/go.mod h1:OojLxIdKm1JAAdh3sL4j4F+vfrLKb7kq1vr8bpyEKgg=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg=
|
github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
|
github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
|
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
@ -31,8 +30,9 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
|
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
|
||||||
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||||
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
|
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
|
||||||
|
@ -53,6 +53,10 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
@ -62,26 +66,26 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||||
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -93,24 +97,23 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
|
k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
|
||||||
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
|
k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
|
||||||
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs=
|
k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc=
|
||||||
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc=
|
k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0=
|
||||||
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
|
k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
|
||||||
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
|
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
|
sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
|
sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||||
|
|
|
@ -49,11 +49,11 @@ type KustomizationSpec struct {
|
||||||
// +optional
|
// +optional
|
||||||
CommonMetadata *CommonMetadata `json:"commonMetadata,omitempty"`
|
CommonMetadata *CommonMetadata `json:"commonMetadata,omitempty"`
|
||||||
|
|
||||||
// DependsOn may contain a meta.NamespacedObjectReference slice
|
// DependsOn may contain a DependencyReference slice
|
||||||
// with references to Kustomization resources that must be ready before this
|
// with references to Kustomization resources that must be ready before this
|
||||||
// Kustomization can be reconciled.
|
// Kustomization can be reconciled.
|
||||||
// +optional
|
// +optional
|
||||||
DependsOn []meta.NamespacedObjectReference `json:"dependsOn,omitempty"`
|
DependsOn []DependencyReference `json:"dependsOn,omitempty"`
|
||||||
|
|
||||||
// Decrypt Kubernetes secrets before applying them on the cluster.
|
// Decrypt Kubernetes secrets before applying them on the cluster.
|
||||||
// +optional
|
// +optional
|
||||||
|
@ -177,10 +177,16 @@ type KustomizationSpec struct {
|
||||||
// +optional
|
// +optional
|
||||||
Wait bool `json:"wait,omitempty"`
|
Wait bool `json:"wait,omitempty"`
|
||||||
|
|
||||||
// Components specifies relative paths to specifications of other Components.
|
// Components specifies relative paths to kustomize Components.
|
||||||
// +optional
|
// +optional
|
||||||
Components []string `json:"components,omitempty"`
|
Components []string `json:"components,omitempty"`
|
||||||
|
|
||||||
|
// IgnoreMissingComponents instructs the controller to ignore Components paths
|
||||||
|
// not found in source by removing them from the generated kustomization.yaml
|
||||||
|
// before running kustomize build.
|
||||||
|
// +optional
|
||||||
|
IgnoreMissingComponents bool `json:"ignoreMissingComponents,omitempty"`
|
||||||
|
|
||||||
// HealthCheckExprs is a list of healthcheck expressions for evaluating the
|
// HealthCheckExprs is a list of healthcheck expressions for evaluating the
|
||||||
// health of custom resources using Common Expression Language (CEL).
|
// health of custom resources using Common Expression Language (CEL).
|
||||||
// The expressions are evaluated only when Wait or HealthChecks are specified.
|
// The expressions are evaluated only when Wait or HealthChecks are specified.
|
||||||
|
@ -297,6 +303,11 @@ type KustomizationStatus struct {
|
||||||
// have been successfully applied.
|
// have been successfully applied.
|
||||||
// +optional
|
// +optional
|
||||||
Inventory *ResourceInventory `json:"inventory,omitempty"`
|
Inventory *ResourceInventory `json:"inventory,omitempty"`
|
||||||
|
|
||||||
|
// History contains a set of snapshots of the last reconciliation attempts
|
||||||
|
// tracking the revision, the state and the duration of each attempt.
|
||||||
|
// +optional
|
||||||
|
History meta.History `json:"history,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTimeout returns the timeout with default.
|
// GetTimeout returns the timeout with default.
|
||||||
|
@ -333,9 +344,19 @@ func (in Kustomization) GetDeletionPolicy() string {
|
||||||
return in.Spec.DeletionPolicy
|
return in.Spec.DeletionPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDependsOn returns the list of dependencies across-namespaces.
|
// GetDependsOn returns the dependencies as a list of meta.NamespacedObjectReference.
|
||||||
|
//
|
||||||
|
// This function makes the Kustomization type conformant with the meta.ObjectWithDependencies interface
|
||||||
|
// and allows the controller-runtime to index Kustomizations by their dependencies.
|
||||||
func (in Kustomization) GetDependsOn() []meta.NamespacedObjectReference {
|
func (in Kustomization) GetDependsOn() []meta.NamespacedObjectReference {
|
||||||
return in.Spec.DependsOn
|
deps := make([]meta.NamespacedObjectReference, len(in.Spec.DependsOn))
|
||||||
|
for i := range in.Spec.DependsOn {
|
||||||
|
deps[i] = meta.NamespacedObjectReference{
|
||||||
|
Name: in.Spec.DependsOn[i].Name,
|
||||||
|
Namespace: in.Spec.DependsOn[i].Namespace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deps
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConditions returns the status conditions of the object.
|
// GetConditions returns the status conditions of the object.
|
||||||
|
|
|
@ -16,7 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
// CrossNamespaceSourceReference contains enough information to let you locate the
|
// CrossNamespaceSourceReference contains enough information to let you locate the
|
||||||
// typed Kubernetes resource object at cluster level.
|
// typed Kubernetes resource object at cluster level.
|
||||||
|
@ -26,7 +28,7 @@ type CrossNamespaceSourceReference struct {
|
||||||
APIVersion string `json:"apiVersion,omitempty"`
|
APIVersion string `json:"apiVersion,omitempty"`
|
||||||
|
|
||||||
// Kind of the referent.
|
// Kind of the referent.
|
||||||
// +kubebuilder:validation:Enum=OCIRepository;GitRepository;Bucket
|
// +kubebuilder:validation:Enum=OCIRepository;GitRepository;Bucket;ExternalArtifact
|
||||||
// +required
|
// +required
|
||||||
Kind string `json:"kind"`
|
Kind string `json:"kind"`
|
||||||
|
|
||||||
|
@ -40,9 +42,31 @@ type CrossNamespaceSourceReference struct {
|
||||||
Namespace string `json:"namespace,omitempty"`
|
Namespace string `json:"namespace,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of the CrossNamespaceSourceReference
|
||||||
|
// in the format "Kind/Name" or "Kind/Namespace/Name" if Namespace is set.
|
||||||
func (s *CrossNamespaceSourceReference) String() string {
|
func (s *CrossNamespaceSourceReference) String() string {
|
||||||
if s.Namespace != "" {
|
if s.Namespace != "" {
|
||||||
return fmt.Sprintf("%s/%s/%s", s.Kind, s.Namespace, s.Name)
|
return fmt.Sprintf("%s/%s/%s", s.Kind, s.Namespace, s.Name)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s/%s", s.Kind, s.Name)
|
return fmt.Sprintf("%s/%s", s.Kind, s.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DependencyReference defines a Kustomization dependency on another Kustomization resource.
|
||||||
|
type DependencyReference struct {
|
||||||
|
// Name of the referent.
|
||||||
|
// +required
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Namespace of the referent, defaults to the namespace of the Kustomization
|
||||||
|
// resource object that contains the reference.
|
||||||
|
// +optional
|
||||||
|
Namespace string `json:"namespace,omitempty"`
|
||||||
|
|
||||||
|
// ReadyExpr is a CEL expression that can be used to assess the readiness
|
||||||
|
// of a dependency. When specified, the built-in readiness check
|
||||||
|
// is replaced by the logic defined in the CEL expression.
|
||||||
|
// To make the CEL expression additive to the built-in readiness check,
|
||||||
|
// the feature gate `AdditiveCELDependencyCheck` must be set to `true`.
|
||||||
|
// +optional
|
||||||
|
ReadyExpr string `json:"readyExpr,omitempty"`
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//go:build !ignore_autogenerated
|
//go:build !ignore_autogenerated
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2023 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -91,6 +91,21 @@ func (in *Decryption) DeepCopy() *Decryption {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *DependencyReference) DeepCopyInto(out *DependencyReference) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DependencyReference.
|
||||||
|
func (in *DependencyReference) DeepCopy() *DependencyReference {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(DependencyReference)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Kustomization) DeepCopyInto(out *Kustomization) {
|
func (in *Kustomization) DeepCopyInto(out *Kustomization) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -160,7 +175,7 @@ func (in *KustomizationSpec) DeepCopyInto(out *KustomizationSpec) {
|
||||||
}
|
}
|
||||||
if in.DependsOn != nil {
|
if in.DependsOn != nil {
|
||||||
in, out := &in.DependsOn, &out.DependsOn
|
in, out := &in.DependsOn, &out.DependsOn
|
||||||
*out = make([]meta.NamespacedObjectReference, len(*in))
|
*out = make([]DependencyReference, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
if in.Decryption != nil {
|
if in.Decryption != nil {
|
||||||
|
@ -177,7 +192,7 @@ func (in *KustomizationSpec) DeepCopyInto(out *KustomizationSpec) {
|
||||||
if in.KubeConfig != nil {
|
if in.KubeConfig != nil {
|
||||||
in, out := &in.KubeConfig, &out.KubeConfig
|
in, out := &in.KubeConfig, &out.KubeConfig
|
||||||
*out = new(meta.KubeConfigReference)
|
*out = new(meta.KubeConfigReference)
|
||||||
**out = **in
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.PostBuild != nil {
|
if in.PostBuild != nil {
|
||||||
in, out := &in.PostBuild, &out.PostBuild
|
in, out := &in.PostBuild, &out.PostBuild
|
||||||
|
@ -245,6 +260,13 @@ func (in *KustomizationStatus) DeepCopyInto(out *KustomizationStatus) {
|
||||||
*out = new(ResourceInventory)
|
*out = new(ResourceInventory)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.History != nil {
|
||||||
|
in, out := &in.History, &out.History
|
||||||
|
*out = make(meta.History, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizationStatus.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizationStatus.
|
||||||
|
|
|
@ -15,6 +15,9 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Package v1beta1 contains API Schema definitions for the kustomize v1beta1 API group
|
// Package v1beta1 contains API Schema definitions for the kustomize v1beta1 API group
|
||||||
|
//
|
||||||
|
// Deprecated: v1beta1 is no longer supported, use v1 instead.
|
||||||
|
//
|
||||||
// +kubebuilder:object:generate=true
|
// +kubebuilder:object:generate=true
|
||||||
// +groupName=kustomize.toolkit.fluxcd.io
|
// +groupName=kustomize.toolkit.fluxcd.io
|
||||||
package v1beta1
|
package v1beta1
|
||||||
|
|
|
@ -272,12 +272,7 @@ const (
|
||||||
|
|
||||||
// +genclient
|
// +genclient
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
// +kubebuilder:resource:shortName=ks
|
// +kubebuilder:skipversion
|
||||||
// +kubebuilder:subresource:status
|
|
||||||
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
|
||||||
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
|
|
||||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
|
|
||||||
// +kubebuilder:deprecatedversion:warning="v1beta1 Kustomization is deprecated, upgrade to v1"
|
|
||||||
|
|
||||||
// Kustomization is the Schema for the kustomizations API.
|
// Kustomization is the Schema for the kustomizations API.
|
||||||
type Kustomization struct {
|
type Kustomization struct {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//go:build !ignore_autogenerated
|
//go:build !ignore_autogenerated
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2023 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//go:build !ignore_autogenerated
|
//go:build !ignore_autogenerated
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2023 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -178,7 +178,7 @@ func (in *KustomizationSpec) DeepCopyInto(out *KustomizationSpec) {
|
||||||
if in.KubeConfig != nil {
|
if in.KubeConfig != nil {
|
||||||
in, out := &in.KubeConfig, &out.KubeConfig
|
in, out := &in.KubeConfig, &out.KubeConfig
|
||||||
*out = new(meta.KubeConfigReference)
|
*out = new(meta.KubeConfigReference)
|
||||||
**out = **in
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.PostBuild != nil {
|
if in.PostBuild != nil {
|
||||||
in, out := &in.PostBuild, &out.PostBuild
|
in, out := &in.PostBuild, &out.PostBuild
|
||||||
|
|
|
@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.16.1
|
controller-gen.kubebuilder.io/version: v0.19.0
|
||||||
name: kustomizations.kustomize.toolkit.fluxcd.io
|
name: kustomizations.kustomize.toolkit.fluxcd.io
|
||||||
spec:
|
spec:
|
||||||
group: kustomize.toolkit.fluxcd.io
|
group: kustomize.toolkit.fluxcd.io
|
||||||
|
@ -71,8 +71,7 @@ spec:
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
components:
|
components:
|
||||||
description: Components specifies relative paths to specifications
|
description: Components specifies relative paths to kustomize Components.
|
||||||
of other Components.
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
@ -123,20 +122,28 @@ spec:
|
||||||
type: string
|
type: string
|
||||||
dependsOn:
|
dependsOn:
|
||||||
description: |-
|
description: |-
|
||||||
DependsOn may contain a meta.NamespacedObjectReference slice
|
DependsOn may contain a DependencyReference slice
|
||||||
with references to Kustomization resources that must be ready before this
|
with references to Kustomization resources that must be ready before this
|
||||||
Kustomization can be reconciled.
|
Kustomization can be reconciled.
|
||||||
items:
|
items:
|
||||||
description: |-
|
description: DependencyReference defines a Kustomization dependency
|
||||||
NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any
|
on another Kustomization resource.
|
||||||
namespace.
|
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the referent.
|
description: Name of the referent.
|
||||||
type: string
|
type: string
|
||||||
namespace:
|
namespace:
|
||||||
description: Namespace of the referent, when not specified it
|
description: |-
|
||||||
acts as LocalObjectReference.
|
Namespace of the referent, defaults to the namespace of the Kustomization
|
||||||
|
resource object that contains the reference.
|
||||||
|
type: string
|
||||||
|
readyExpr:
|
||||||
|
description: |-
|
||||||
|
ReadyExpr is a CEL expression that can be used to assess the readiness
|
||||||
|
of a dependency. When specified, the built-in readiness check
|
||||||
|
is replaced by the logic defined in the CEL expression.
|
||||||
|
To make the CEL expression additive to the built-in readiness check,
|
||||||
|
the feature gate `AdditiveCELDependencyCheck` must be set to `true`.
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
|
@ -210,6 +217,12 @@ spec:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
|
ignoreMissingComponents:
|
||||||
|
description: |-
|
||||||
|
IgnoreMissingComponents instructs the controller to ignore Components paths
|
||||||
|
not found in source by removing them from the generated kustomization.yaml
|
||||||
|
before running kustomize build.
|
||||||
|
type: boolean
|
||||||
images:
|
images:
|
||||||
description: |-
|
description: |-
|
||||||
Images is a list of (image name, new name, new tag or digest)
|
Images is a list of (image name, new name, new tag or digest)
|
||||||
|
@ -256,16 +269,54 @@ spec:
|
||||||
a controller level fallback for when KustomizationSpec.ServiceAccountName
|
a controller level fallback for when KustomizationSpec.ServiceAccountName
|
||||||
is empty.
|
is empty.
|
||||||
properties:
|
properties:
|
||||||
|
configMapRef:
|
||||||
|
description: |-
|
||||||
|
ConfigMapRef holds an optional name of a ConfigMap that contains
|
||||||
|
the following keys:
|
||||||
|
|
||||||
|
- `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or
|
||||||
|
`generic`. Required.
|
||||||
|
- `cluster`: the fully qualified resource name of the Kubernetes
|
||||||
|
cluster in the cloud provider API. Not used by the `generic`
|
||||||
|
provider. Required when one of `address` or `ca.crt` is not set.
|
||||||
|
- `address`: the address of the Kubernetes API server. Required
|
||||||
|
for `generic`. For the other providers, if not specified, the
|
||||||
|
first address in the cluster resource will be used, and if
|
||||||
|
specified, it must match one of the addresses in the cluster
|
||||||
|
resource.
|
||||||
|
If audiences is not set, will be used as the audience for the
|
||||||
|
`generic` provider.
|
||||||
|
- `ca.crt`: the optional PEM-encoded CA certificate for the
|
||||||
|
Kubernetes API server. If not set, the controller will use the
|
||||||
|
CA certificate from the cluster resource.
|
||||||
|
- `audiences`: the optional audiences as a list of
|
||||||
|
line-break-separated strings for the Kubernetes ServiceAccount
|
||||||
|
token. Defaults to the `address` for the `generic` provider, or
|
||||||
|
to specific values for the other providers depending on the
|
||||||
|
provider.
|
||||||
|
- `serviceAccountName`: the optional name of the Kubernetes
|
||||||
|
ServiceAccount in the same namespace that should be used
|
||||||
|
for authentication. If not specified, the controller
|
||||||
|
ServiceAccount will be used.
|
||||||
|
|
||||||
|
Mutually exclusive with SecretRef.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name of the referent.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
secretRef:
|
secretRef:
|
||||||
description: |-
|
description: |-
|
||||||
SecretRef holds the name of a secret that contains a key with
|
SecretRef holds an optional name of a secret that contains a key with
|
||||||
the kubeconfig file as the value. If no key is set, the key will default
|
the kubeconfig file as the value. If no key is set, the key will default
|
||||||
to 'value'.
|
to 'value'. Mutually exclusive with ConfigMapRef.
|
||||||
It is recommended that the kubeconfig is self-contained, and the secret
|
It is recommended that the kubeconfig is self-contained, and the secret
|
||||||
is regularly updated if credentials such as a cloud-access-token expire.
|
is regularly updated if credentials such as a cloud-access-token expire.
|
||||||
Cloud specific `cmd-path` auth helpers will not function without adding
|
Cloud specific `cmd-path` auth helpers will not function without adding
|
||||||
binaries and credentials to the Pod that is responsible for reconciling
|
binaries and credentials to the Pod that is responsible for reconciling
|
||||||
Kubernetes resources.
|
Kubernetes resources. Supported only for the generic provider.
|
||||||
properties:
|
properties:
|
||||||
key:
|
key:
|
||||||
description: Key in the Secret, when not specified an implementation-specific
|
description: Key in the Secret, when not specified an implementation-specific
|
||||||
|
@ -277,9 +328,14 @@ spec:
|
||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
required:
|
|
||||||
- secretRef
|
|
||||||
type: object
|
type: object
|
||||||
|
x-kubernetes-validations:
|
||||||
|
- message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef
|
||||||
|
must be specified
|
||||||
|
rule: has(self.configMapRef) || has(self.secretRef)
|
||||||
|
- message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef
|
||||||
|
must be specified
|
||||||
|
rule: '!has(self.configMapRef) || !has(self.secretRef)'
|
||||||
namePrefix:
|
namePrefix:
|
||||||
description: NamePrefix will prefix the names of all managed resources.
|
description: NamePrefix will prefix the names of all managed resources.
|
||||||
maxLength: 200
|
maxLength: 200
|
||||||
|
@ -438,6 +494,7 @@ spec:
|
||||||
- OCIRepository
|
- OCIRepository
|
||||||
- GitRepository
|
- GitRepository
|
||||||
- Bucket
|
- Bucket
|
||||||
|
- ExternalArtifact
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
description: Name of the referent.
|
description: Name of the referent.
|
||||||
|
@ -540,6 +597,57 @@ spec:
|
||||||
- type
|
- type
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
|
history:
|
||||||
|
description: |-
|
||||||
|
History contains a set of snapshots of the last reconciliation attempts
|
||||||
|
tracking the revision, the state and the duration of each attempt.
|
||||||
|
items:
|
||||||
|
description: |-
|
||||||
|
Snapshot represents a point-in-time record of a group of resources reconciliation,
|
||||||
|
including timing information, status, and a unique digest identifier.
|
||||||
|
properties:
|
||||||
|
digest:
|
||||||
|
description: Digest is the checksum in the format `<algo>:<hex>`
|
||||||
|
of the resources in this snapshot.
|
||||||
|
type: string
|
||||||
|
firstReconciled:
|
||||||
|
description: FirstReconciled is the time when this revision
|
||||||
|
was first reconciled to the cluster.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
lastReconciled:
|
||||||
|
description: LastReconciled is the time when this revision was
|
||||||
|
last reconciled to the cluster.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
lastReconciledDuration:
|
||||||
|
description: LastReconciledDuration is time it took to reconcile
|
||||||
|
the resources in this revision.
|
||||||
|
type: string
|
||||||
|
lastReconciledStatus:
|
||||||
|
description: LastReconciledStatus is the status of the last
|
||||||
|
reconciliation.
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: Metadata contains additional information about
|
||||||
|
the snapshot.
|
||||||
|
type: object
|
||||||
|
totalReconciliations:
|
||||||
|
description: TotalReconciliations is the total number of reconciliations
|
||||||
|
that have occurred for this snapshot.
|
||||||
|
format: int64
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- digest
|
||||||
|
- firstReconciled
|
||||||
|
- lastReconciled
|
||||||
|
- lastReconciledDuration
|
||||||
|
- lastReconciledStatus
|
||||||
|
- totalReconciliations
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
inventory:
|
inventory:
|
||||||
description: |-
|
description: |-
|
||||||
Inventory contains the list of Kubernetes resource object references that
|
Inventory contains the list of Kubernetes resource object references that
|
||||||
|
@ -601,574 +709,6 @@ spec:
|
||||||
storage: true
|
storage: true
|
||||||
subresources:
|
subresources:
|
||||||
status: {}
|
status: {}
|
||||||
- additionalPrinterColumns:
|
|
||||||
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
|
||||||
name: Ready
|
|
||||||
type: string
|
|
||||||
- jsonPath: .status.conditions[?(@.type=="Ready")].message
|
|
||||||
name: Status
|
|
||||||
type: string
|
|
||||||
- jsonPath: .metadata.creationTimestamp
|
|
||||||
name: Age
|
|
||||||
type: date
|
|
||||||
deprecated: true
|
|
||||||
deprecationWarning: v1beta1 Kustomization is deprecated, upgrade to v1
|
|
||||||
name: v1beta1
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
description: Kustomization is the Schema for the kustomizations API.
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: |-
|
|
||||||
APIVersion defines the versioned schema of this representation of an object.
|
|
||||||
Servers should convert recognized schemas to the latest internal value, and
|
|
||||||
may reject unrecognized values.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind is a string value representing the REST resource this object represents.
|
|
||||||
Servers may infer this from the endpoint the client submits requests to.
|
|
||||||
Cannot be updated.
|
|
||||||
In CamelCase.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
|
||||||
type: string
|
|
||||||
metadata:
|
|
||||||
type: object
|
|
||||||
spec:
|
|
||||||
description: KustomizationSpec defines the desired state of a kustomization.
|
|
||||||
properties:
|
|
||||||
decryption:
|
|
||||||
description: Decrypt Kubernetes secrets before applying them on the
|
|
||||||
cluster.
|
|
||||||
properties:
|
|
||||||
provider:
|
|
||||||
description: Provider is the name of the decryption engine.
|
|
||||||
enum:
|
|
||||||
- sops
|
|
||||||
type: string
|
|
||||||
secretRef:
|
|
||||||
description: The secret name containing the private OpenPGP keys
|
|
||||||
used for decryption.
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
description: Name of the referent.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- provider
|
|
||||||
type: object
|
|
||||||
dependsOn:
|
|
||||||
description: |-
|
|
||||||
DependsOn may contain a meta.NamespacedObjectReference slice
|
|
||||||
with references to Kustomization resources that must be ready before this
|
|
||||||
Kustomization can be reconciled.
|
|
||||||
items:
|
|
||||||
description: |-
|
|
||||||
NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any
|
|
||||||
namespace.
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
description: Name of the referent.
|
|
||||||
type: string
|
|
||||||
namespace:
|
|
||||||
description: Namespace of the referent, when not specified it
|
|
||||||
acts as LocalObjectReference.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
force:
|
|
||||||
default: false
|
|
||||||
description: |-
|
|
||||||
Force instructs the controller to recreate resources
|
|
||||||
when patching fails due to an immutable field change.
|
|
||||||
type: boolean
|
|
||||||
healthChecks:
|
|
||||||
description: A list of resources to be included in the health assessment.
|
|
||||||
items:
|
|
||||||
description: |-
|
|
||||||
NamespacedObjectKindReference contains enough information to locate the typed referenced Kubernetes resource object
|
|
||||||
in any namespace.
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: API version of the referent, if not specified the
|
|
||||||
Kubernetes preferred version will be used.
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: Kind of the referent.
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name of the referent.
|
|
||||||
type: string
|
|
||||||
namespace:
|
|
||||||
description: Namespace of the referent, when not specified it
|
|
||||||
acts as LocalObjectReference.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kind
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
images:
|
|
||||||
description: |-
|
|
||||||
Images is a list of (image name, new name, new tag or digest)
|
|
||||||
for changing image names, tags or digests. This can also be achieved with a
|
|
||||||
patch, but this operator is simpler to specify.
|
|
||||||
items:
|
|
||||||
description: Image contains an image name, a new name, a new tag
|
|
||||||
or digest, which will replace the original name and tag.
|
|
||||||
properties:
|
|
||||||
digest:
|
|
||||||
description: |-
|
|
||||||
Digest is the value used to replace the original image tag.
|
|
||||||
If digest is present NewTag value is ignored.
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name is a tag-less image name.
|
|
||||||
type: string
|
|
||||||
newName:
|
|
||||||
description: NewName is the value used to replace the original
|
|
||||||
name.
|
|
||||||
type: string
|
|
||||||
newTag:
|
|
||||||
description: NewTag is the value used to replace the original
|
|
||||||
tag.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
interval:
|
|
||||||
description: The interval at which to reconcile the Kustomization.
|
|
||||||
type: string
|
|
||||||
kubeConfig:
|
|
||||||
description: |-
|
|
||||||
The KubeConfig for reconciling the Kustomization on a remote cluster.
|
|
||||||
When specified, KubeConfig takes precedence over ServiceAccountName.
|
|
||||||
properties:
|
|
||||||
secretRef:
|
|
||||||
description: |-
|
|
||||||
SecretRef holds the name to a secret that contains a 'value' key with
|
|
||||||
the kubeconfig file as the value. It must be in the same namespace as
|
|
||||||
the Kustomization.
|
|
||||||
It is recommended that the kubeconfig is self-contained, and the secret
|
|
||||||
is regularly updated if credentials such as a cloud-access-token expire.
|
|
||||||
Cloud specific `cmd-path` auth helpers will not function without adding
|
|
||||||
binaries and credentials to the Pod that is responsible for reconciling
|
|
||||||
the Kustomization.
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
description: Name of the referent.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- secretRef
|
|
||||||
type: object
|
|
||||||
patches:
|
|
||||||
description: |-
|
|
||||||
Strategic merge and JSON patches, defined as inline YAML objects,
|
|
||||||
capable of targeting objects based on kind, label and annotation selectors.
|
|
||||||
items:
|
|
||||||
description: |-
|
|
||||||
Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should
|
|
||||||
be applied to.
|
|
||||||
properties:
|
|
||||||
patch:
|
|
||||||
description: |-
|
|
||||||
Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with
|
|
||||||
an array of operation objects.
|
|
||||||
type: string
|
|
||||||
target:
|
|
||||||
description: Target points to the resources that the patch document
|
|
||||||
should be applied to.
|
|
||||||
properties:
|
|
||||||
annotationSelector:
|
|
||||||
description: |-
|
|
||||||
AnnotationSelector is a string that follows the label selection expression
|
|
||||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
|
|
||||||
It matches with the resource annotations.
|
|
||||||
type: string
|
|
||||||
group:
|
|
||||||
description: |-
|
|
||||||
Group is the API group to select resources from.
|
|
||||||
Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources.
|
|
||||||
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind of the API Group to select resources from.
|
|
||||||
Together with Group and Version it is capable of unambiguously
|
|
||||||
identifying and/or selecting resources.
|
|
||||||
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
|
||||||
type: string
|
|
||||||
labelSelector:
|
|
||||||
description: |-
|
|
||||||
LabelSelector is a string that follows the label selection expression
|
|
||||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
|
|
||||||
It matches with the resource labels.
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name to match resources with.
|
|
||||||
type: string
|
|
||||||
namespace:
|
|
||||||
description: Namespace to select resources from.
|
|
||||||
type: string
|
|
||||||
version:
|
|
||||||
description: |-
|
|
||||||
Version of the API Group to select resources from.
|
|
||||||
Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources.
|
|
||||||
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- patch
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
patchesJson6902:
|
|
||||||
description: JSON 6902 patches, defined as inline YAML objects.
|
|
||||||
items:
|
|
||||||
description: JSON6902Patch contains a JSON6902 patch and the target
|
|
||||||
the patch should be applied to.
|
|
||||||
properties:
|
|
||||||
patch:
|
|
||||||
description: Patch contains the JSON6902 patch document with
|
|
||||||
an array of operation objects.
|
|
||||||
items:
|
|
||||||
description: |-
|
|
||||||
JSON6902 is a JSON6902 operation object.
|
|
||||||
https://datatracker.ietf.org/doc/html/rfc6902#section-4
|
|
||||||
properties:
|
|
||||||
from:
|
|
||||||
description: |-
|
|
||||||
From contains a JSON-pointer value that references a location within the target document where the operation is
|
|
||||||
performed. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations.
|
|
||||||
type: string
|
|
||||||
op:
|
|
||||||
description: |-
|
|
||||||
Op indicates the operation to perform. Its value MUST be one of "add", "remove", "replace", "move", "copy", or
|
|
||||||
"test".
|
|
||||||
https://datatracker.ietf.org/doc/html/rfc6902#section-4
|
|
||||||
enum:
|
|
||||||
- test
|
|
||||||
- remove
|
|
||||||
- add
|
|
||||||
- replace
|
|
||||||
- move
|
|
||||||
- copy
|
|
||||||
type: string
|
|
||||||
path:
|
|
||||||
description: |-
|
|
||||||
Path contains the JSON-pointer value that references a location within the target document where the operation
|
|
||||||
is performed. The meaning of the value depends on the value of Op.
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
description: |-
|
|
||||||
Value contains a valid JSON structure. The meaning of the value depends on the value of Op, and is NOT taken into
|
|
||||||
account by all operations.
|
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
|
||||||
required:
|
|
||||||
- op
|
|
||||||
- path
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
target:
|
|
||||||
description: Target points to the resources that the patch document
|
|
||||||
should be applied to.
|
|
||||||
properties:
|
|
||||||
annotationSelector:
|
|
||||||
description: |-
|
|
||||||
AnnotationSelector is a string that follows the label selection expression
|
|
||||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
|
|
||||||
It matches with the resource annotations.
|
|
||||||
type: string
|
|
||||||
group:
|
|
||||||
description: |-
|
|
||||||
Group is the API group to select resources from.
|
|
||||||
Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources.
|
|
||||||
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind of the API Group to select resources from.
|
|
||||||
Together with Group and Version it is capable of unambiguously
|
|
||||||
identifying and/or selecting resources.
|
|
||||||
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
|
||||||
type: string
|
|
||||||
labelSelector:
|
|
||||||
description: |-
|
|
||||||
LabelSelector is a string that follows the label selection expression
|
|
||||||
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api
|
|
||||||
It matches with the resource labels.
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name to match resources with.
|
|
||||||
type: string
|
|
||||||
namespace:
|
|
||||||
description: Namespace to select resources from.
|
|
||||||
type: string
|
|
||||||
version:
|
|
||||||
description: |-
|
|
||||||
Version of the API Group to select resources from.
|
|
||||||
Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources.
|
|
||||||
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- patch
|
|
||||||
- target
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
patchesStrategicMerge:
|
|
||||||
description: Strategic merge patches, defined as inline YAML objects.
|
|
||||||
items:
|
|
||||||
x-kubernetes-preserve-unknown-fields: true
|
|
||||||
type: array
|
|
||||||
path:
|
|
||||||
description: |-
|
|
||||||
Path to the directory containing the kustomization.yaml file, or the
|
|
||||||
set of plain YAMLs a kustomization.yaml should be generated for.
|
|
||||||
Defaults to 'None', which translates to the root path of the SourceRef.
|
|
||||||
type: string
|
|
||||||
postBuild:
|
|
||||||
description: |-
|
|
||||||
PostBuild describes which actions to perform on the YAML manifest
|
|
||||||
generated by building the kustomize overlay.
|
|
||||||
properties:
|
|
||||||
substitute:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
Substitute holds a map of key/value pairs.
|
|
||||||
The variables defined in your YAML manifests
|
|
||||||
that match any of the keys defined in the map
|
|
||||||
will be substituted with the set value.
|
|
||||||
Includes support for bash string replacement functions
|
|
||||||
e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}.
|
|
||||||
type: object
|
|
||||||
substituteFrom:
|
|
||||||
description: |-
|
|
||||||
SubstituteFrom holds references to ConfigMaps and Secrets containing
|
|
||||||
the variables and their values to be substituted in the YAML manifests.
|
|
||||||
The ConfigMap and the Secret data keys represent the var names and they
|
|
||||||
must match the vars declared in the manifests for the substitution to happen.
|
|
||||||
items:
|
|
||||||
description: |-
|
|
||||||
SubstituteReference contains a reference to a resource containing
|
|
||||||
the variables name and value.
|
|
||||||
properties:
|
|
||||||
kind:
|
|
||||||
description: Kind of the values referent, valid values are
|
|
||||||
('Secret', 'ConfigMap').
|
|
||||||
enum:
|
|
||||||
- Secret
|
|
||||||
- ConfigMap
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: |-
|
|
||||||
Name of the values referent. Should reside in the same namespace as the
|
|
||||||
referring resource.
|
|
||||||
maxLength: 253
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kind
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
type: object
|
|
||||||
prune:
|
|
||||||
description: Prune enables garbage collection.
|
|
||||||
type: boolean
|
|
||||||
retryInterval:
|
|
||||||
description: |-
|
|
||||||
The interval at which to retry a previously failed reconciliation.
|
|
||||||
When not specified, the controller uses the KustomizationSpec.Interval
|
|
||||||
value to retry failures.
|
|
||||||
type: string
|
|
||||||
serviceAccountName:
|
|
||||||
description: |-
|
|
||||||
The name of the Kubernetes service account to impersonate
|
|
||||||
when reconciling this Kustomization.
|
|
||||||
type: string
|
|
||||||
sourceRef:
|
|
||||||
description: Reference of the source where the kustomization file
|
|
||||||
is.
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: API version of the referent
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: Kind of the referent
|
|
||||||
enum:
|
|
||||||
- GitRepository
|
|
||||||
- Bucket
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name of the referent
|
|
||||||
type: string
|
|
||||||
namespace:
|
|
||||||
description: Namespace of the referent, defaults to the Kustomization
|
|
||||||
namespace
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kind
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
suspend:
|
|
||||||
description: |-
|
|
||||||
This flag tells the controller to suspend subsequent kustomize executions,
|
|
||||||
it does not apply to already started executions. Defaults to false.
|
|
||||||
type: boolean
|
|
||||||
targetNamespace:
|
|
||||||
description: |-
|
|
||||||
TargetNamespace sets or overrides the namespace in the
|
|
||||||
kustomization.yaml file.
|
|
||||||
maxLength: 63
|
|
||||||
minLength: 1
|
|
||||||
type: string
|
|
||||||
timeout:
|
|
||||||
description: |-
|
|
||||||
Timeout for validation, apply and health checking operations.
|
|
||||||
Defaults to 'Interval' duration.
|
|
||||||
type: string
|
|
||||||
validation:
|
|
||||||
description: |-
|
|
||||||
Validate the Kubernetes objects before applying them on the cluster.
|
|
||||||
The validation strategy can be 'client' (local dry-run), 'server'
|
|
||||||
(APIServer dry-run) or 'none'.
|
|
||||||
When 'Force' is 'true', validation will fallback to 'client' if set to
|
|
||||||
'server' because server-side validation is not supported in this scenario.
|
|
||||||
enum:
|
|
||||||
- none
|
|
||||||
- client
|
|
||||||
- server
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- interval
|
|
||||||
- prune
|
|
||||||
- sourceRef
|
|
||||||
type: object
|
|
||||||
status:
|
|
||||||
default:
|
|
||||||
observedGeneration: -1
|
|
||||||
description: KustomizationStatus defines the observed state of a kustomization.
|
|
||||||
properties:
|
|
||||||
conditions:
|
|
||||||
items:
|
|
||||||
description: Condition contains details for one aspect of the current
|
|
||||||
state of this API Resource.
|
|
||||||
properties:
|
|
||||||
lastTransitionTime:
|
|
||||||
description: |-
|
|
||||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
|
||||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
|
||||||
format: date-time
|
|
||||||
type: string
|
|
||||||
message:
|
|
||||||
description: |-
|
|
||||||
message is a human readable message indicating details about the transition.
|
|
||||||
This may be an empty string.
|
|
||||||
maxLength: 32768
|
|
||||||
type: string
|
|
||||||
observedGeneration:
|
|
||||||
description: |-
|
|
||||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
|
||||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
|
||||||
with respect to the current state of the instance.
|
|
||||||
format: int64
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
|
||||||
reason:
|
|
||||||
description: |-
|
|
||||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
|
||||||
Producers of specific condition types may define expected values and meanings for this field,
|
|
||||||
and whether the values are considered a guaranteed API.
|
|
||||||
The value should be a CamelCase string.
|
|
||||||
This field may not be empty.
|
|
||||||
maxLength: 1024
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
|
||||||
type: string
|
|
||||||
status:
|
|
||||||
description: status of the condition, one of True, False, Unknown.
|
|
||||||
enum:
|
|
||||||
- "True"
|
|
||||||
- "False"
|
|
||||||
- Unknown
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
|
||||||
maxLength: 316
|
|
||||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- lastTransitionTime
|
|
||||||
- message
|
|
||||||
- reason
|
|
||||||
- status
|
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
lastAppliedRevision:
|
|
||||||
description: |-
|
|
||||||
The last successfully applied revision.
|
|
||||||
The revision format for Git sources is <branch|tag>/<commit-sha>.
|
|
||||||
type: string
|
|
||||||
lastAttemptedRevision:
|
|
||||||
description: LastAttemptedRevision is the revision of the last reconciliation
|
|
||||||
attempt.
|
|
||||||
type: string
|
|
||||||
lastHandledReconcileAt:
|
|
||||||
description: |-
|
|
||||||
LastHandledReconcileAt holds the value of the most recent
|
|
||||||
reconcile request value, so a change of the annotation value
|
|
||||||
can be detected.
|
|
||||||
type: string
|
|
||||||
observedGeneration:
|
|
||||||
description: ObservedGeneration is the last reconciled generation.
|
|
||||||
format: int64
|
|
||||||
type: integer
|
|
||||||
snapshot:
|
|
||||||
description: The last successfully applied revision metadata.
|
|
||||||
properties:
|
|
||||||
checksum:
|
|
||||||
description: The manifests sha1 checksum.
|
|
||||||
type: string
|
|
||||||
entries:
|
|
||||||
description: A list of Kubernetes kinds grouped by namespace.
|
|
||||||
items:
|
|
||||||
description: |-
|
|
||||||
Snapshot holds the metadata of namespaced
|
|
||||||
Kubernetes objects
|
|
||||||
properties:
|
|
||||||
kinds:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
description: The list of Kubernetes kinds.
|
|
||||||
type: object
|
|
||||||
namespace:
|
|
||||||
description: The namespace of this entry.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kinds
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
required:
|
|
||||||
- checksum
|
|
||||||
- entries
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
served: true
|
|
||||||
storage: false
|
|
||||||
subresources:
|
|
||||||
status: {}
|
|
||||||
- additionalPrinterColumns:
|
- additionalPrinterColumns:
|
||||||
- jsonPath: .metadata.creationTimestamp
|
- jsonPath: .metadata.creationTimestamp
|
||||||
name: Age
|
name: Age
|
||||||
|
@ -1347,16 +887,54 @@ spec:
|
||||||
a controller level fallback for when KustomizationSpec.ServiceAccountName
|
a controller level fallback for when KustomizationSpec.ServiceAccountName
|
||||||
is empty.
|
is empty.
|
||||||
properties:
|
properties:
|
||||||
|
configMapRef:
|
||||||
|
description: |-
|
||||||
|
ConfigMapRef holds an optional name of a ConfigMap that contains
|
||||||
|
the following keys:
|
||||||
|
|
||||||
|
- `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or
|
||||||
|
`generic`. Required.
|
||||||
|
- `cluster`: the fully qualified resource name of the Kubernetes
|
||||||
|
cluster in the cloud provider API. Not used by the `generic`
|
||||||
|
provider. Required when one of `address` or `ca.crt` is not set.
|
||||||
|
- `address`: the address of the Kubernetes API server. Required
|
||||||
|
for `generic`. For the other providers, if not specified, the
|
||||||
|
first address in the cluster resource will be used, and if
|
||||||
|
specified, it must match one of the addresses in the cluster
|
||||||
|
resource.
|
||||||
|
If audiences is not set, will be used as the audience for the
|
||||||
|
`generic` provider.
|
||||||
|
- `ca.crt`: the optional PEM-encoded CA certificate for the
|
||||||
|
Kubernetes API server. If not set, the controller will use the
|
||||||
|
CA certificate from the cluster resource.
|
||||||
|
- `audiences`: the optional audiences as a list of
|
||||||
|
line-break-separated strings for the Kubernetes ServiceAccount
|
||||||
|
token. Defaults to the `address` for the `generic` provider, or
|
||||||
|
to specific values for the other providers depending on the
|
||||||
|
provider.
|
||||||
|
- `serviceAccountName`: the optional name of the Kubernetes
|
||||||
|
ServiceAccount in the same namespace that should be used
|
||||||
|
for authentication. If not specified, the controller
|
||||||
|
ServiceAccount will be used.
|
||||||
|
|
||||||
|
Mutually exclusive with SecretRef.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name of the referent.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
secretRef:
|
secretRef:
|
||||||
description: |-
|
description: |-
|
||||||
SecretRef holds the name of a secret that contains a key with
|
SecretRef holds an optional name of a secret that contains a key with
|
||||||
the kubeconfig file as the value. If no key is set, the key will default
|
the kubeconfig file as the value. If no key is set, the key will default
|
||||||
to 'value'.
|
to 'value'. Mutually exclusive with ConfigMapRef.
|
||||||
It is recommended that the kubeconfig is self-contained, and the secret
|
It is recommended that the kubeconfig is self-contained, and the secret
|
||||||
is regularly updated if credentials such as a cloud-access-token expire.
|
is regularly updated if credentials such as a cloud-access-token expire.
|
||||||
Cloud specific `cmd-path` auth helpers will not function without adding
|
Cloud specific `cmd-path` auth helpers will not function without adding
|
||||||
binaries and credentials to the Pod that is responsible for reconciling
|
binaries and credentials to the Pod that is responsible for reconciling
|
||||||
Kubernetes resources.
|
Kubernetes resources. Supported only for the generic provider.
|
||||||
properties:
|
properties:
|
||||||
key:
|
key:
|
||||||
description: Key in the Secret, when not specified an implementation-specific
|
description: Key in the Secret, when not specified an implementation-specific
|
||||||
|
@ -1368,9 +946,14 @@ spec:
|
||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
type: object
|
type: object
|
||||||
required:
|
|
||||||
- secretRef
|
|
||||||
type: object
|
type: object
|
||||||
|
x-kubernetes-validations:
|
||||||
|
- message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef
|
||||||
|
must be specified
|
||||||
|
rule: has(self.configMapRef) || has(self.secretRef)
|
||||||
|
- message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef
|
||||||
|
must be specified
|
||||||
|
rule: '!has(self.configMapRef) || !has(self.secretRef)'
|
||||||
patches:
|
patches:
|
||||||
description: |-
|
description: |-
|
||||||
Strategic merge and JSON patches, defined as inline YAML objects,
|
Strategic merge and JSON patches, defined as inline YAML objects,
|
||||||
|
|
|
@ -2,8 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
namespace: kustomize-system
|
namespace: kustomize-system
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v1.6.0/source-controller.crds.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v1.7.0-rc.3/source-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v1.6.0/source-controller.deployment.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v1.7.0-rc.3/source-controller.deployment.yaml
|
||||||
- ../crd
|
- ../crd
|
||||||
- ../rbac
|
- ../rbac
|
||||||
- ../manager
|
- ../manager
|
||||||
|
|
|
@ -89,14 +89,14 @@ overridden if its key matches a common one.</p>
|
||||||
<td>
|
<td>
|
||||||
<code>dependsOn</code><br>
|
<code>dependsOn</code><br>
|
||||||
<em>
|
<em>
|
||||||
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/meta#NamespacedObjectReference">
|
<a href="#kustomize.toolkit.fluxcd.io/v1.DependencyReference">
|
||||||
[]github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference
|
[]DependencyReference
|
||||||
</a>
|
</a>
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>DependsOn may contain a meta.NamespacedObjectReference slice
|
<p>DependsOn may contain a DependencyReference slice
|
||||||
with references to Kustomization resources that must be ready before this
|
with references to Kustomization resources that must be ready before this
|
||||||
Kustomization can be reconciled.</p>
|
Kustomization can be reconciled.</p>
|
||||||
</td>
|
</td>
|
||||||
|
@ -392,7 +392,21 @@ resources. When enabled, the HealthChecks are ignored. Defaults to false.</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Components specifies relative paths to specifications of other Components.</p>
|
<p>Components specifies relative paths to kustomize Components.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>ignoreMissingComponents</code><br>
|
||||||
|
<em>
|
||||||
|
bool
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>IgnoreMissingComponents instructs the controller to ignore Components paths
|
||||||
|
not found in source by removing them from the generated kustomization.yaml
|
||||||
|
before running kustomize build.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -609,6 +623,67 @@ field.</p>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<h3 id="kustomize.toolkit.fluxcd.io/v1.DependencyReference">DependencyReference
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
(<em>Appears on:</em>
|
||||||
|
<a href="#kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec</a>)
|
||||||
|
</p>
|
||||||
|
<p>DependencyReference defines a Kustomization dependency on another Kustomization resource.</p>
|
||||||
|
<div class="md-typeset__scrollwrap">
|
||||||
|
<div class="md-typeset__table">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Field</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>name</code><br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Name of the referent.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>namespace</code><br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>Namespace of the referent, defaults to the namespace of the Kustomization
|
||||||
|
resource object that contains the reference.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>readyExpr</code><br>
|
||||||
|
<em>
|
||||||
|
string
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>ReadyExpr is a CEL expression that can be used to assess the readiness
|
||||||
|
of a dependency. When specified, the built-in readiness check
|
||||||
|
is replaced by the logic defined in the CEL expression.
|
||||||
|
To make the CEL expression additive to the built-in readiness check,
|
||||||
|
the feature gate <code>AdditiveCELDependencyCheck</code> must be set to <code>true</code>.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<h3 id="kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec
|
<h3 id="kustomize.toolkit.fluxcd.io/v1.KustomizationSpec">KustomizationSpec
|
||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
|
@ -647,14 +722,14 @@ overridden if its key matches a common one.</p>
|
||||||
<td>
|
<td>
|
||||||
<code>dependsOn</code><br>
|
<code>dependsOn</code><br>
|
||||||
<em>
|
<em>
|
||||||
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/meta#NamespacedObjectReference">
|
<a href="#kustomize.toolkit.fluxcd.io/v1.DependencyReference">
|
||||||
[]github.com/fluxcd/pkg/apis/meta.NamespacedObjectReference
|
[]DependencyReference
|
||||||
</a>
|
</a>
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>DependsOn may contain a meta.NamespacedObjectReference slice
|
<p>DependsOn may contain a DependencyReference slice
|
||||||
with references to Kustomization resources that must be ready before this
|
with references to Kustomization resources that must be ready before this
|
||||||
Kustomization can be reconciled.</p>
|
Kustomization can be reconciled.</p>
|
||||||
</td>
|
</td>
|
||||||
|
@ -950,7 +1025,21 @@ resources. When enabled, the HealthChecks are ignored. Defaults to false.</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>Components specifies relative paths to specifications of other Components.</p>
|
<p>Components specifies relative paths to kustomize Components.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>ignoreMissingComponents</code><br>
|
||||||
|
<em>
|
||||||
|
bool
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>IgnoreMissingComponents instructs the controller to ignore Components paths
|
||||||
|
not found in source by removing them from the generated kustomization.yaml
|
||||||
|
before running kustomize build.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1086,6 +1175,21 @@ ResourceInventory
|
||||||
have been successfully applied.</p>
|
have been successfully applied.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>history</code><br>
|
||||||
|
<em>
|
||||||
|
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/meta#History">
|
||||||
|
github.com/fluxcd/pkg/apis/meta.History
|
||||||
|
</a>
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>History contains a set of snapshots of the last reconciliation attempts
|
||||||
|
tracking the revision, the state and the duration of each attempt.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -117,6 +117,7 @@ Artifact containing the YAML manifests. It has two required fields:
|
||||||
+ [GitRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/gitrepositories.md)
|
+ [GitRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/gitrepositories.md)
|
||||||
+ [OCIRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/ocirepositories.md)
|
+ [OCIRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/ocirepositories.md)
|
||||||
+ [Bucket](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/buckets.md)
|
+ [Bucket](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/buckets.md)
|
||||||
|
+ [ExternalArtifact](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/externalartifacts.md) (requires `--feature-gates=ExternalArtifact=true` flag)
|
||||||
- `name`: The Name of the referred Source object.
|
- `name`: The Name of the referred Source object.
|
||||||
|
|
||||||
#### Cross-namespace references
|
#### Cross-namespace references
|
||||||
|
@ -487,6 +488,51 @@ is running before deploying applications inside the mesh.
|
||||||
**Note:** Circular dependencies between Kustomizations must be avoided,
|
**Note:** Circular dependencies between Kustomizations must be avoided,
|
||||||
otherwise the interdependent Kustomizations will never be applied on the cluster.
|
otherwise the interdependent Kustomizations will never be applied on the cluster.
|
||||||
|
|
||||||
|
#### Dependency Ready Expression
|
||||||
|
|
||||||
|
`.spec.dependsOn[].readyExpr` is an optional field that can be used to define a CEL expression
|
||||||
|
to determine the readiness of a Kustomization dependency.
|
||||||
|
|
||||||
|
This is helpful for when custom logic is needed to determine if a dependency is ready.
|
||||||
|
For example, when performing a lockstep upgrade, the `readyExpr` can be used to
|
||||||
|
verify that a dependency has a matching version label before proceeding with the
|
||||||
|
reconciliation of the dependent Kustomization.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
|
kind: Kustomization
|
||||||
|
metadata:
|
||||||
|
name: app-backend
|
||||||
|
namespace: apps
|
||||||
|
labels:
|
||||||
|
app/version: v1.2.3
|
||||||
|
---
|
||||||
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
|
kind: Kustomization
|
||||||
|
metadata:
|
||||||
|
name: app-frontend
|
||||||
|
namespace: apps
|
||||||
|
labels:
|
||||||
|
app/version: v1.2.3
|
||||||
|
spec:
|
||||||
|
dependsOn:
|
||||||
|
- name: app-backend
|
||||||
|
readyExpr: >
|
||||||
|
dep.metadata.labels['app/version'] == self.metadata.labels['app/version'] &&
|
||||||
|
dep.status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'True') &&
|
||||||
|
dep.metadata.generation == dep.status.observedGeneration
|
||||||
|
```
|
||||||
|
|
||||||
|
The CEL expression contains the following variables:
|
||||||
|
|
||||||
|
- `dep`: The dependency Kustomization object being evaluated.
|
||||||
|
- `self`: The Kustomization object being reconciled.
|
||||||
|
|
||||||
|
**Note:** When `readyExpr` is specified, the built-in readiness check is replaced by the logic
|
||||||
|
defined in the CEL expression. You can configure the controller to run both the CEL expression
|
||||||
|
evaluation and the built-in readiness check, with the `AdditiveCELDependencyCheck`
|
||||||
|
[feature gate](https://fluxcd.io/flux/components/kustomize/options/#feature-gates).
|
||||||
|
|
||||||
### Service Account reference
|
### Service Account reference
|
||||||
|
|
||||||
`.spec.serviceAccountName` is an optional field used to specify the
|
`.spec.serviceAccountName` is an optional field used to specify the
|
||||||
|
@ -618,6 +664,7 @@ metadata:
|
||||||
namespace: flux-system
|
namespace: flux-system
|
||||||
spec:
|
spec:
|
||||||
# ...omitted for brevity
|
# ...omitted for brevity
|
||||||
|
ignoreMissingComponents: false
|
||||||
components:
|
components:
|
||||||
- ../ingress
|
- ../ingress
|
||||||
- ../tls
|
- ../tls
|
||||||
|
@ -625,6 +672,11 @@ spec:
|
||||||
|
|
||||||
**Note:** The components paths must be local and relative to the path specified by `.spec.path`.
|
**Note:** The components paths must be local and relative to the path specified by `.spec.path`.
|
||||||
|
|
||||||
|
With `.spec.ignoreMissingComponents` you can specify whether the controller
|
||||||
|
should ignore the component paths that are missing from the source. By default,
|
||||||
|
it is set to `false`, meaning that the controller will fail the reconciliation
|
||||||
|
if any of the specified paths are missing from the source.
|
||||||
|
|
||||||
**Warning:** Components are an alpha feature in Kustomize and are therefore
|
**Warning:** Components are an alpha feature in Kustomize and are therefore
|
||||||
considered experimental in Flux. No guarantees are provided as the feature may
|
considered experimental in Flux. No guarantees are provided as the feature may
|
||||||
be modified in backwards incompatible ways or removed without warning.
|
be modified in backwards incompatible ways or removed without warning.
|
||||||
|
@ -639,6 +691,10 @@ With `.spec.postBuild.substituteFrom` you can provide a list of ConfigMaps and
|
||||||
Secrets from which the variables are loaded. The ConfigMap and Secret data keys
|
Secrets from which the variables are loaded. The ConfigMap and Secret data keys
|
||||||
are used as the variable names.
|
are used as the variable names.
|
||||||
|
|
||||||
|
To make a Kustomization react immediately to changes in the referenced Secret
|
||||||
|
or ConfigMap see [this](#reacting-immediately-to-configuration-dependencies)
|
||||||
|
section.
|
||||||
|
|
||||||
The `.spec.postBuild.substituteFrom.optional` field indicates how the
|
The `.spec.postBuild.substituteFrom.optional` field indicates how the
|
||||||
controller should handle a referenced ConfigMap or Secret being absent
|
controller should handle a referenced ConfigMap or Secret being absent
|
||||||
at reconciliation time. The controller's default behavior ― with
|
at reconciliation time. The controller's default behavior ― with
|
||||||
|
@ -699,7 +755,7 @@ spec:
|
||||||
# Fail if this Secret does not exist.
|
# Fail if this Secret does not exist.
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** For substituting variables in a secret, `.spec.stringData` field must be used i.e:
|
For substituting variables in a secret, `.spec.stringData` field must be used i.e:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
|
@ -713,11 +769,11 @@ stringData:
|
||||||
token: ${token}
|
token: ${token}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** The var values which are specified in-line with `substitute`
|
The var values which are specified in-line with `substitute`
|
||||||
take precedence over the ones derived from `substituteFrom`.
|
take precedence over the ones derived from `substituteFrom`.
|
||||||
When var values for the same variable keys are derived from multiple
|
When var values for the same variable keys are derived from multiple
|
||||||
`ConfigMaps` or `Secrets` referenced in the `substituteFrom` list, then the
|
`ConfigMaps` or `Secrets` referenced in the `substituteFrom` list,
|
||||||
first take precedence over the later values.
|
the later values overwrite earlier values.
|
||||||
|
|
||||||
**Note:** If you want to avoid var substitutions in scripts embedded in
|
**Note:** If you want to avoid var substitutions in scripts embedded in
|
||||||
ConfigMaps or container commands, you must use the format `$var` instead of
|
ConfigMaps or container commands, you must use the format `$var` instead of
|
||||||
|
@ -791,14 +847,44 @@ with:
|
||||||
kustomize.toolkit.fluxcd.io/force: enabled
|
kustomize.toolkit.fluxcd.io/force: enabled
|
||||||
```
|
```
|
||||||
|
|
||||||
### KubeConfig reference
|
### KubeConfig (Remote clusters)
|
||||||
|
|
||||||
|
With the `.spec.kubeConfig` field a Kustomization
|
||||||
|
can apply and manage resources on a remote cluster.
|
||||||
|
|
||||||
|
Two authentication alternatives are available:
|
||||||
|
|
||||||
|
- `.spec.kubeConfig.secretRef`: Secret-based authentication using a
|
||||||
|
static kubeconfig stored in a Kubernetes Secret in the same namespace
|
||||||
|
as the Kustomization.
|
||||||
|
- `.spec.kubeConfig.configMapRef` (Recommended): Secret-less authentication
|
||||||
|
building a kubeconfig dynamically with parameters stored in a Kubernetes
|
||||||
|
ConfigMap in the same namespace as the Kustomization via workload identity.
|
||||||
|
|
||||||
|
To make a Kustomization react immediately to changes in the referenced Secret
|
||||||
|
or ConfigMap see [this](#reacting-immediately-to-configuration-dependencies)
|
||||||
|
section.
|
||||||
|
|
||||||
|
When both `.spec.kubeConfig` and
|
||||||
|
[`.spec.serviceAccountName`](#service-account-reference) are specified,
|
||||||
|
the controller will impersonate the ServiceAccount on the target cluster,
|
||||||
|
i.e. a ServiceAccount with name `.spec.serviceAccountName` must exist in
|
||||||
|
the target cluster inside a namespace with the same name as the namespace
|
||||||
|
of the Kustomization. For example, if the Kustomization is in the namespace
|
||||||
|
`apps` of the cluster where Flux is running, then the ServiceAccount
|
||||||
|
must be in the `apps` namespace of the target remote cluster, and have the
|
||||||
|
name `.spec.serviceAccountName`. In other words, the namespace of the
|
||||||
|
Kustomization must exist both in the cluster where Flux is running
|
||||||
|
and in the target remote cluster where Flux will apply resources.
|
||||||
|
|
||||||
|
#### Secret-based authentication
|
||||||
|
|
||||||
`.spec.kubeConfig.secretRef.Name` is an optional field to specify the name of
|
`.spec.kubeConfig.secretRef.Name` is an optional field to specify the name of
|
||||||
the secret containing a KubeConfig. If specified, objects will be applied,
|
the secret containing a KubeConfig. If specified, objects will be applied,
|
||||||
health-checked, pruned, and deleted for the default cluster specified in that
|
health-checked, pruned, and deleted for the default cluster specified in that
|
||||||
KubeConfig instead of using the in-cluster ServiceAccount.
|
KubeConfig instead of using the in-cluster ServiceAccount.
|
||||||
|
|
||||||
The secret defined in the `kubeConfig.SecretRef` must exist in the same
|
The secret defined in the `.spec.kubeConfig.secretRef` must exist in the same
|
||||||
namespace as the Kustomization. On every reconciliation, the KubeConfig bytes
|
namespace as the Kustomization. On every reconciliation, the KubeConfig bytes
|
||||||
will be loaded from the `.secretRef.key` key (default: `value` or `value.yaml`)
|
will be loaded from the `.secretRef.key` key (default: `value` or `value.yaml`)
|
||||||
of the Secret’s data , and the Secret can thus be regularly updated if
|
of the Secret’s data , and the Secret can thus be regularly updated if
|
||||||
|
@ -822,12 +908,88 @@ stringData:
|
||||||
environment, or credential files from the kustomize-controller Pod.
|
environment, or credential files from the kustomize-controller Pod.
|
||||||
This matches the constraints of KubeConfigs from current Cluster API providers.
|
This matches the constraints of KubeConfigs from current Cluster API providers.
|
||||||
KubeConfigs with `cmd-path` in them likely won't work without a custom,
|
KubeConfigs with `cmd-path` in them likely won't work without a custom,
|
||||||
per-provider installation of kustomize-controller.
|
per-provider installation of kustomize-controller. For more information, see
|
||||||
|
[remote clusters/Cluster-API](#remote-cluster-api-clusters).
|
||||||
|
|
||||||
When both `.spec.kubeConfig` and `.spec.ServiceAccountName` are specified,
|
#### Secret-less authentication
|
||||||
the controller will impersonate the service account on the target cluster.
|
|
||||||
|
|
||||||
For more information, see [remote clusters/Cluster-API](#remote-clusterscluster-api).
|
The field `.spec.kubeConfig.configMapRef.name` can be used to specify the
|
||||||
|
name of a ConfigMap in the same namespace as the Kustomization containing
|
||||||
|
parameters for secret-less authentication via workload identity. The
|
||||||
|
supported keys inside the `.data` field of the ConfigMap are:
|
||||||
|
|
||||||
|
- `.data.provider`: The provider to use. One of `aws`, `azure`, `gcp`,
|
||||||
|
or `generic`. Required. The `aws` provider is used for connecting to
|
||||||
|
remote EKS clusters, `azure` for AKS, `gcp` for GKE, and `generic`
|
||||||
|
for Kubernetes OIDC authentication between clusters. For the
|
||||||
|
`generic` provider, the remote cluster must be configured to trust
|
||||||
|
the OIDC issuer of the cluster where Flux is running.
|
||||||
|
- `.data.cluster`: The fully qualified resource name of the Kubernetes
|
||||||
|
cluster in the cloud provider API. Not used by the `generic`
|
||||||
|
provider. Required when one of `.data.address` or `.data["ca.crt"]` is
|
||||||
|
not set, or if the provider is `aws` (required for defining a region).
|
||||||
|
- `.data.address`: The address of the Kubernetes API server. Required
|
||||||
|
for `generic`. For the other providers, if not specified, the
|
||||||
|
first address in the cluster resource will be used, and if
|
||||||
|
specified, it must match one of the addresses in the cluster
|
||||||
|
resource.
|
||||||
|
If `audiences` is not set, will be used as the audience for the
|
||||||
|
`generic` provider.
|
||||||
|
- `.data["ca.crt"]`: The optional PEM-encoded CA certificate for the
|
||||||
|
Kubernetes API server. If not set, the controller will use the
|
||||||
|
CA certificate from the cluster resource.
|
||||||
|
- `.data.audiences`: The optional audiences as a list of
|
||||||
|
line-break-separated strings for the Kubernetes ServiceAccount token.
|
||||||
|
Defaults to the address for the `generic` provider, or to specific
|
||||||
|
values for the other providers depending on the provider.
|
||||||
|
- `.data.serviceAccountName`: The optional name of the Kubernetes
|
||||||
|
ServiceAccount in the same namespace that should be used
|
||||||
|
for authentication. If not specified, the controller
|
||||||
|
ServiceAccount will be used. Not confuse with the ServiceAccount
|
||||||
|
used for impersonation, which is specified with
|
||||||
|
[`.spec.serviceAccountName`](#service-account-reference) directly
|
||||||
|
in the Kustomization spec and must exist in the target remote cluster.
|
||||||
|
|
||||||
|
The `.data.cluster` field, when specified, must have the following formats:
|
||||||
|
|
||||||
|
- `aws`: `arn:<partition>:eks:<region>:<account-id>:cluster/<cluster-name>`
|
||||||
|
- `azure`: `/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ContainerService/managedClusters/<cluster-name>`
|
||||||
|
- `gcp`: `projects/<project-id>/locations/<location>/clusters/<cluster-name>`
|
||||||
|
|
||||||
|
For complete guides on workload identity and setting up permissions for
|
||||||
|
this feature, see the following docs:
|
||||||
|
|
||||||
|
- [EKS](/flux/integrations/aws/#for-amazon-elastic-kubernetes-service)
|
||||||
|
- [AKS](/flux/integrations/azure/#for-azure-kubernetes-service)
|
||||||
|
- [GKE](/flux/integrations/gcp/#for-google-kubernetes-engine)
|
||||||
|
- [Generic](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#configuring-the-api-server)
|
||||||
|
|
||||||
|
Example for an EKS cluster:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||||
|
kind: Kustomization
|
||||||
|
metadata:
|
||||||
|
name: backend
|
||||||
|
namespace: apps
|
||||||
|
spec:
|
||||||
|
... # other fields omitted for brevity
|
||||||
|
kubeConfig:
|
||||||
|
configMapRef:
|
||||||
|
name: kubeconfig
|
||||||
|
serviceAccountName: apps-sa # optional. must exist in the target cluster. user for impersonation
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: kubeconfig
|
||||||
|
namespace: apps
|
||||||
|
data:
|
||||||
|
kubeConfig:
|
||||||
|
provider: aws
|
||||||
|
cluster: arn:aws:eks:eu-central-1:123456789012:cluster/my-cluster
|
||||||
|
serviceAccountName: apps-iam-role # optional. maps to an AWS IAM Role. used for authentication
|
||||||
|
```
|
||||||
|
|
||||||
### Decryption
|
### Decryption
|
||||||
|
|
||||||
|
@ -856,6 +1018,9 @@ The `.spec.decryption` field has the following subfields:
|
||||||
- `.serviceAccountName`: The name of the service account used for
|
- `.serviceAccountName`: The name of the service account used for
|
||||||
secret-less authentication with KMS services from cloud providers.
|
secret-less authentication with KMS services from cloud providers.
|
||||||
|
|
||||||
|
To make a Kustomization react immediately to changes in the referenced Secret
|
||||||
|
see [this](#reacting-immediately-to-configuration-dependencies) section.
|
||||||
|
|
||||||
For a complete guide on how to set up authentication for KMS services from
|
For a complete guide on how to set up authentication for KMS services from
|
||||||
cloud providers, see the integration [docs](/flux/integrations/).
|
cloud providers, see the integration [docs](/flux/integrations/).
|
||||||
|
|
||||||
|
@ -1353,9 +1518,9 @@ When the flag is set, all Kustomizations which don't have [`.spec.serviceAccount
|
||||||
specified will use the service account name provided by
|
specified will use the service account name provided by
|
||||||
`--default-service-account=<SA Name>` in the namespace of the object.
|
`--default-service-account=<SA Name>` in the namespace of the object.
|
||||||
|
|
||||||
### Remote clusters/Cluster-API
|
### Remote Cluster API clusters
|
||||||
|
|
||||||
With the [`.spec.kubeConfig` field](#kubeconfig-reference) a Kustomization can be fully
|
Using a [`.spec.kubeConfig` reference](#kubeconfig-remote-clusters) a Kustomization can be fully
|
||||||
reconciled on a remote cluster. This composes well with Cluster API bootstrap
|
reconciled on a remote cluster. This composes well with Cluster API bootstrap
|
||||||
providers such as CAPBK (kubeadm), CAPA (AWS) and others.
|
providers such as CAPBK (kubeadm), CAPA (AWS) and others.
|
||||||
|
|
||||||
|
@ -1430,155 +1595,24 @@ Kustomization object itself, it will fall back to these defaults.
|
||||||
|
|
||||||
See also the [workload identity](/flux/installation/configuration/workload-identity/) docs.
|
See also the [workload identity](/flux/installation/configuration/workload-identity/) docs.
|
||||||
|
|
||||||
#### AWS KMS
|
#### Cloud Provider KMS Services
|
||||||
|
|
||||||
While making use of the [IAM OIDC provider](https://eksctl.io/usage/iamserviceaccounts/)
|
For cloud provider KMS services, please refer to the specific sections in the integration guides:
|
||||||
on your EKS cluster, you can create an IAM Role and Service Account with access
|
|
||||||
to AWS KMS (using at least `kms:Decrypt` and `kms:DescribeKey`). Once these are
|
|
||||||
created, you can annotate the kustomize-controller Service Account with the
|
|
||||||
Role ARN, granting the controller permission to decrypt the Secrets. Please refer
|
|
||||||
to the [SOPS guide](https://fluxcd.io/flux/guides/mozilla-sops/#aws) for detailed steps.
|
|
||||||
|
|
||||||
```sh
|
Service-specific configuration:
|
||||||
kubectl -n flux-system annotate serviceaccount kustomize-controller \
|
|
||||||
--field-manager=flux-client-side-apply \
|
|
||||||
eks.amazonaws.com/role-arn='arn:aws:iam::<ACCOUNT_ID>:role/<KMS-ROLE-NAME>'
|
|
||||||
```
|
|
||||||
|
|
||||||
Furthermore, you can also use the usual [environment variables used for specifying AWS
|
- [AWS KMS](https://fluxcd.io/flux/integrations/aws/#for-amazon-key-management-service)
|
||||||
credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html#envvars-list),
|
- [Azure Key Vault](https://fluxcd.io/flux/integrations/azure/#for-azure-key-vault)
|
||||||
by patching the kustomize-controller Deployment:
|
- [GCP KMS](https://fluxcd.io/flux/integrations/gcp/#for-google-cloud-key-management-service)
|
||||||
|
|
||||||
```yaml
|
Controller-level configuration:
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: kustomize-controller
|
|
||||||
namespace: flux-system
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: manager
|
|
||||||
env:
|
|
||||||
- name: AWS_ACCESS_KEY_ID
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: aws-creds
|
|
||||||
key: awsAccessKeyID
|
|
||||||
- name: AWS_SECRET_ACCESS_KEY
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: aws-creds
|
|
||||||
key: awsSecretAccessKey
|
|
||||||
- name: AWS_SESSION_TOKEN
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: aws-creds
|
|
||||||
key: awsSessionToken
|
|
||||||
```
|
|
||||||
|
|
||||||
In addition to this, the
|
- [AWS](https://fluxcd.io/flux/integrations/aws/#at-the-controller-level)
|
||||||
[general SOPS documentation around KMS AWS applies](https://github.com/mozilla/sops#27kms-aws-profiles),
|
- [Azure](https://fluxcd.io/flux/integrations/azure/#at-the-controller-level)
|
||||||
allowing you to specify e.g. a `SOPS_KMS_ARN` environment variable.
|
- [GCP](https://fluxcd.io/flux/integrations/gcp/#at-the-controller-level)
|
||||||
|
|
||||||
**Note:**: If you are mounting a secret containing the AWS credentials as a
|
These guides provide detailed instructions for setting up authentication,
|
||||||
file in the `kustomize-controller` Pod, you need to specify an environment
|
permissions, and controller configuration for each cloud provider.
|
||||||
variable `$HOME`, since the AWS credentials file is expected to be present at
|
|
||||||
`~/.aws`. For example:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
env:
|
|
||||||
- name: HOME
|
|
||||||
value: /home/{$USER}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Azure Key Vault
|
|
||||||
|
|
||||||
##### Workload Identity
|
|
||||||
|
|
||||||
If you have Workload Identity set up on your AKS cluster, you can establish
|
|
||||||
a federated identity between the kustomize-controller ServiceAccount and an
|
|
||||||
identity that has "Decrypt" role on the Azure Key Vault. Once, this is done
|
|
||||||
you can label and annotate the kustomize-controller ServiceAccount and Pod
|
|
||||||
with the patch shown below:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
resources:
|
|
||||||
- gotk-components.yaml
|
|
||||||
- gotk-sync.yaml
|
|
||||||
patches:
|
|
||||||
- patch: |-
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: kustomize-controller
|
|
||||||
namespace: flux-system
|
|
||||||
annotations:
|
|
||||||
azure.workload.identity/client-id: <AZURE_CLIENT_ID>
|
|
||||||
labels:
|
|
||||||
azure.workload.identity/use: "true"
|
|
||||||
- patch: |-
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: kustomize-controller
|
|
||||||
namespace: flux-system
|
|
||||||
labels:
|
|
||||||
azure.workload.identity/use: "true"
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
azure.workload.identity/use: "true"
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Kubelet Identity
|
|
||||||
|
|
||||||
If the kubelet managed identity has `Decrypt` permissions on Azure Key Vault,
|
|
||||||
no additional configuration is required for the kustomize-controller to decrypt
|
|
||||||
data.
|
|
||||||
|
|
||||||
#### GCP KMS
|
|
||||||
|
|
||||||
While making use of Google Cloud Platform, the [`GOOGLE_APPLICATION_CREDENTIALS`
|
|
||||||
environment variable](https://cloud.google.com/docs/authentication/production)
|
|
||||||
is automatically taken into account.
|
|
||||||
[Granting permissions](https://cloud.google.com/kms/docs/reference/permissions-and-roles)
|
|
||||||
to the Service Account attached to this will therefore be sufficient to decrypt
|
|
||||||
data. When running outside GCP, it is possible to manually patch the
|
|
||||||
kustomize-controller Deployment with a valid set of (mounted) credentials.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: kustomize-controller
|
|
||||||
namespace: flux-system
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: manager
|
|
||||||
env:
|
|
||||||
- name: GOOGLE_APPLICATION_CREDENTIALS
|
|
||||||
value: /var/gcp/credentials.json
|
|
||||||
volumeMounts:
|
|
||||||
- name: gcp-credentials
|
|
||||||
mountPath: /var/gcp/
|
|
||||||
readOnly: true
|
|
||||||
volumes:
|
|
||||||
- name: gcp-credentials
|
|
||||||
secret:
|
|
||||||
secretName: mysecret
|
|
||||||
items:
|
|
||||||
- key: credentials
|
|
||||||
path: credentials.json
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Hashicorp Vault
|
#### Hashicorp Vault
|
||||||
|
|
||||||
|
@ -1602,6 +1636,48 @@ spec:
|
||||||
value: <token>
|
value: <token>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### SOPS Age Keys
|
||||||
|
|
||||||
|
To configure global decryption for SOPS Age keys, use the `--sops-age-secret`
|
||||||
|
controller flag to specify a Kubernetes Secret containing the Age private keys.
|
||||||
|
|
||||||
|
First, create a Secret containing the Age private keys with the `.agekey` suffix:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: sops-age-keys
|
||||||
|
namespace: flux-system
|
||||||
|
stringData:
|
||||||
|
identity1.agekey: <identity1 key>
|
||||||
|
identity2.agekey: <identity1 key>
|
||||||
|
```
|
||||||
|
|
||||||
|
The Secret must be in the same namespace as the kustomize-controller Deployment.
|
||||||
|
|
||||||
|
Then, patch the kustomize-controller Deployment to add the `--sops-age-secret` flag:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: kustomize-controller
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: manager
|
||||||
|
args:
|
||||||
|
- --sops-age-secret=sops-age-keys
|
||||||
|
```
|
||||||
|
|
||||||
|
The field `.spec.decryption.secretRef` in the Kustomization will take precedence
|
||||||
|
in case both the controller flag and the Kustomization field are set.
|
||||||
|
|
||||||
### Kustomize secretGenerator
|
### Kustomize secretGenerator
|
||||||
|
|
||||||
SOPS encrypted data can be stored as a base64 encoded Secret, which enables the
|
SOPS encrypted data can be stored as a base64 encoded Secret, which enables the
|
||||||
|
@ -1897,6 +1973,29 @@ the controller. The Flux CLI offer commands for filtering the logs for a
|
||||||
specific Kustomization, e.g.
|
specific Kustomization, e.g.
|
||||||
`flux logs --level=error --kind=Kustomization --name=<kustomization-name>`.
|
`flux logs --level=error --kind=Kustomization --name=<kustomization-name>`.
|
||||||
|
|
||||||
|
### Reacting immediately to configuration dependencies
|
||||||
|
|
||||||
|
To trigger a reconciliation when changes occur in referenced
|
||||||
|
Secrets or ConfigMaps, you can set the following label on the
|
||||||
|
Secret or ConfigMap:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
reconcile.fluxcd.io/watch: Enabled
|
||||||
|
```
|
||||||
|
|
||||||
|
An alternative to labeling every Secret or ConfigMap is
|
||||||
|
setting the `--watch-configs-label-selector=owner!=helm`
|
||||||
|
[flag](https://fluxcd.io/flux/components/kustomize/options/#flags)
|
||||||
|
in kustomize-controller, which allows watching all Secrets and
|
||||||
|
ConfigMaps except for Helm storage Secrets.
|
||||||
|
|
||||||
|
**Note**: A reconciliation will be triggered for an event on a
|
||||||
|
referenced Secret/ConfigMap even if it's marked as optional in
|
||||||
|
the `.spec.postBuild.substituteFrom` field, including deletion
|
||||||
|
events.
|
||||||
|
|
||||||
## Kustomization Status
|
## Kustomization Status
|
||||||
|
|
||||||
### Conditions
|
### Conditions
|
||||||
|
@ -1974,6 +2073,37 @@ configuration issue in the Kustomization spec. When a reconciliation fails, the
|
||||||
`Reconciling` Condition `reason` would be `ProgressingWithRetry`. When the
|
`Reconciling` Condition `reason` would be `ProgressingWithRetry`. When the
|
||||||
reconciliation is performed again after the failure, the `reason` is updated to `Progressing`.
|
reconciliation is performed again after the failure, the `reason` is updated to `Progressing`.
|
||||||
|
|
||||||
|
### History
|
||||||
|
|
||||||
|
The kustomize-controller maintains a history of the last 5 reconciliations
|
||||||
|
in `.status.history`, including the digest of the applied manifests, the
|
||||||
|
source and origin revision, the timestamps and the duration of the reconciliations,
|
||||||
|
the status and the total number of times a specific digest was reconciled.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
status:
|
||||||
|
history:
|
||||||
|
- digest: sha256:43ad78c94b2655429d84f21488f29d7cca9cd45b7f54d2b27e16bbec8eff9228
|
||||||
|
firstReconciled: "2025-08-15T10:11:00Z"
|
||||||
|
lastReconciled: "2025-08-15T11:12:00Z"
|
||||||
|
lastReconciledDuration: 2.818583s
|
||||||
|
lastReconciledStatus: ReconciliationSucceeded
|
||||||
|
totalReconciliations: 2
|
||||||
|
metadata:
|
||||||
|
revision: "v1.0.1@sha1:450796ddb2ab6724ee1cc32a4be56da032d1cca0"
|
||||||
|
- digest: sha256:ec8dbfe61777b65001190260cf873ffe454451bd2e464bd6f9a154cffcdcd7e5
|
||||||
|
firstReconciled: "2025-07-14T13:10:00Z"
|
||||||
|
lastReconciled: "2025-08-15T10:00:00Z"
|
||||||
|
lastReconciledDuration: 49.813292s
|
||||||
|
lastReconciledStatus: HealthCheckFailed
|
||||||
|
totalReconciliations: 120
|
||||||
|
metadata:
|
||||||
|
revision: "v1.0.0@sha1:67e2c98a60dc92283531412a9e604dd4bae005a9"
|
||||||
|
```
|
||||||
|
|
||||||
|
The kustomize-controller deduplicates entries based on the digest and status, with the
|
||||||
|
most recent reconciliation being the first entry in the list.
|
||||||
|
|
||||||
### Inventory
|
### Inventory
|
||||||
|
|
||||||
In order to perform operations such as drift detection, garbage collection, etc.
|
In order to perform operations such as drift detection, garbage collection, etc.
|
||||||
|
|
214
go.mod
214
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/fluxcd/kustomize-controller
|
module github.com/fluxcd/kustomize-controller
|
||||||
|
|
||||||
go 1.24.0
|
go 1.25.0
|
||||||
|
|
||||||
replace github.com/fluxcd/kustomize-controller/api => ./api
|
replace github.com/fluxcd/kustomize-controller/api => ./api
|
||||||
|
|
||||||
|
@ -9,100 +9,105 @@ replace github.com/fluxcd/kustomize-controller/api => ./api
|
||||||
replace github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be
|
replace github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/kms v1.21.2
|
cloud.google.com/go/kms v1.22.0
|
||||||
filippo.io/age v1.2.1
|
filippo.io/age v1.2.1
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.3
|
github.com/aws/aws-sdk-go-v2 v1.38.3
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.67
|
github.com/aws/aws-sdk-go-v2/credentials v1.18.10
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1
|
github.com/cyphar/filepath-securejoin v0.4.1
|
||||||
github.com/dimchansky/utfbom v1.1.1
|
github.com/dimchansky/utfbom v1.1.1
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.13
|
github.com/fluxcd/cli-utils v0.36.0-flux.15
|
||||||
github.com/fluxcd/kustomize-controller/api v1.6.0
|
github.com/fluxcd/kustomize-controller/api v1.6.0
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0
|
github.com/fluxcd/pkg/apis/acl v0.9.0
|
||||||
github.com/fluxcd/pkg/apis/event v0.17.0
|
github.com/fluxcd/pkg/apis/event v0.19.0
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.10.0
|
github.com/fluxcd/pkg/apis/kustomize v1.12.0
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0
|
github.com/fluxcd/pkg/apis/meta v1.21.0
|
||||||
github.com/fluxcd/pkg/auth v0.16.0
|
github.com/fluxcd/pkg/auth v0.30.0
|
||||||
github.com/fluxcd/pkg/cache v0.9.0
|
github.com/fluxcd/pkg/cache v0.11.0
|
||||||
github.com/fluxcd/pkg/http/fetch v0.16.0
|
github.com/fluxcd/pkg/http/fetch v0.19.0
|
||||||
github.com/fluxcd/pkg/kustomize v1.18.0
|
github.com/fluxcd/pkg/kustomize v1.21.0
|
||||||
github.com/fluxcd/pkg/runtime v0.60.0
|
github.com/fluxcd/pkg/runtime v0.83.0
|
||||||
github.com/fluxcd/pkg/ssa v0.48.0
|
github.com/fluxcd/pkg/ssa v0.53.0
|
||||||
github.com/fluxcd/pkg/tar v0.12.0
|
github.com/fluxcd/pkg/tar v0.14.0
|
||||||
github.com/fluxcd/pkg/testserver v0.11.0
|
github.com/fluxcd/pkg/testserver v0.13.0
|
||||||
github.com/fluxcd/source-controller/api v1.6.0
|
github.com/fluxcd/source-controller/api v1.7.0-rc.3
|
||||||
github.com/getsops/sops/v3 v3.10.2
|
github.com/getsops/sops/v3 v3.10.2
|
||||||
github.com/hashicorp/vault/api v1.16.0
|
github.com/google/cel-go v0.26.1
|
||||||
github.com/onsi/gomega v1.37.0
|
github.com/hashicorp/vault/api v1.20.0
|
||||||
|
github.com/onsi/gomega v1.38.2
|
||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/ory/dockertest/v3 v3.12.0
|
github.com/ory/dockertest/v3 v3.12.0
|
||||||
github.com/spf13/pflag v1.0.6
|
github.com/spf13/pflag v1.0.7
|
||||||
golang.org/x/net v0.40.0
|
golang.org/x/net v0.43.0
|
||||||
golang.org/x/oauth2 v0.30.0
|
golang.org/x/oauth2 v0.30.0
|
||||||
k8s.io/api v0.33.0
|
k8s.io/api v0.34.0
|
||||||
k8s.io/apimachinery v0.33.0
|
k8s.io/apimachinery v0.34.0
|
||||||
k8s.io/client-go v0.33.0
|
k8s.io/client-go v0.34.0
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e
|
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
|
||||||
sigs.k8s.io/controller-runtime v0.21.0
|
sigs.k8s.io/controller-runtime v0.22.0
|
||||||
sigs.k8s.io/kustomize/api v0.19.0
|
sigs.k8s.io/kustomize/api v0.20.1
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pin kustomize to v5.6.0
|
// Pin kustomize to v5.7.1
|
||||||
replace (
|
replace (
|
||||||
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.19.0
|
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.20.1
|
||||||
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.19.0
|
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.20.1
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cel.dev/expr v0.22.1 // indirect
|
cel.dev/expr v0.24.0 // indirect
|
||||||
cloud.google.com/go v0.120.1 // indirect
|
cloud.google.com/go v0.121.6 // indirect
|
||||||
cloud.google.com/go/auth v0.16.1 // indirect
|
cloud.google.com/go/auth v0.16.5 // 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.6.0 // indirect
|
cloud.google.com/go/compute/metadata v0.8.0 // indirect
|
||||||
cloud.google.com/go/iam v1.5.2 // indirect
|
cloud.google.com/go/iam v1.5.2 // indirect
|
||||||
cloud.google.com/go/longrunning v0.6.7 // indirect
|
cloud.google.com/go/longrunning v0.6.7 // indirect
|
||||||
cloud.google.com/go/monitoring v1.24.2 // indirect
|
cloud.google.com/go/monitoring v1.24.2 // indirect
|
||||||
cloud.google.com/go/storage v1.51.0 // indirect
|
cloud.google.com/go/storage v1.56.0 // indirect
|
||||||
dario.cat/mergo v1.0.1 // indirect
|
dario.cat/mergo v1.0.1 // indirect
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 // indirect
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect
|
||||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||||
github.com/ProtonMail/go-crypto v1.2.0 // indirect
|
github.com/ProtonMail/go-crypto v1.2.0 // indirect
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect
|
github.com/aws/aws-sdk-go-v2/config v1.31.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ecr v1.50.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/eks v1.73.1 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 // indirect
|
||||||
github.com/aws/smithy-go v1.22.3 // indirect
|
github.com/aws/smithy-go v1.23.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||||
|
@ -110,13 +115,13 @@ require (
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/chai2010/gettext-go v1.0.3 // indirect
|
github.com/chai2010/gettext-go v1.0.3 // indirect
|
||||||
github.com/cloudflare/circl v1.6.1 // indirect
|
github.com/cloudflare/circl v1.6.1 // indirect
|
||||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect
|
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
|
||||||
github.com/containerd/continuity v0.4.5 // indirect
|
github.com/containerd/continuity v0.4.5 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/docker/cli v28.1.1+incompatible // indirect
|
github.com/docker/cli v28.3.3+incompatible // indirect
|
||||||
github.com/docker/docker v28.1.1+incompatible // indirect
|
github.com/docker/docker v28.3.3+incompatible // indirect
|
||||||
github.com/docker/docker-credential-helpers v0.8.2 // indirect
|
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||||
github.com/docker/go-connections v0.5.0 // indirect
|
github.com/docker/go-connections v0.5.0 // indirect
|
||||||
github.com/docker/go-units v0.5.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
||||||
|
@ -126,47 +131,46 @@ require (
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
||||||
github.com/fatih/color v1.18.0 // indirect
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/fluxcd/pkg/envsubst v1.4.0 // indirect
|
github.com/fluxcd/pkg/envsubst v1.5.0 // indirect
|
||||||
github.com/fluxcd/pkg/sourceignore v0.12.0 // indirect
|
github.com/fluxcd/pkg/sourceignore v0.14.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||||
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e // indirect
|
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e // indirect
|
||||||
github.com/go-errors/errors v1.5.1 // indirect
|
github.com/go-errors/errors v1.5.1 // indirect
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||||
github.com/go-git/go-billy/v5 v5.6.2 // indirect
|
github.com/go-git/go-billy/v5 v5.6.2 // indirect
|
||||||
github.com/go-git/go-git/v5 v5.16.0 // indirect
|
github.com/go-git/go-git/v5 v5.16.2 // indirect
|
||||||
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
|
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
|
||||||
github.com/go-logr/logr v1.4.2 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-logr/zapr v1.3.0 // indirect
|
github.com/go-logr/zapr v1.3.0 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||||
github.com/go-openapi/swag v0.23.1 // indirect
|
github.com/go-openapi/swag v0.23.1 // indirect
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||||
github.com/google/btree v1.1.3 // indirect
|
github.com/google/btree v1.1.3 // indirect
|
||||||
github.com/google/cel-go v0.23.2 // indirect
|
github.com/google/gnostic-models v0.7.0 // indirect
|
||||||
github.com/google/gnostic-models v0.6.9 // indirect
|
|
||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/google/go-containerregistry v0.20.3 // indirect
|
github.com/google/go-containerregistry v0.20.6 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||||
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect
|
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect
|
||||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect
|
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect
|
||||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
||||||
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
|
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.1-vault-7 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
@ -186,7 +190,7 @@ require (
|
||||||
github.com/moby/sys/user v0.4.0 // indirect
|
github.com/moby/sys/user v0.4.0 // indirect
|
||||||
github.com/moby/term v0.5.2 // indirect
|
github.com/moby/term v0.5.2 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||||
|
@ -197,10 +201,11 @@ require (
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||||
github.com/prometheus/client_golang v1.22.0 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.23.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
github.com/prometheus/client_model v0.6.2 // indirect
|
||||||
github.com/prometheus/common v0.63.0 // indirect
|
github.com/prometheus/common v0.65.0 // indirect
|
||||||
github.com/prometheus/procfs v0.16.1 // indirect
|
github.com/prometheus/procfs v0.17.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
|
@ -216,43 +221,46 @@ require (
|
||||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||||
github.com/zeebo/errs v1.4.0 // indirect
|
github.com/zeebo/errs v1.4.0 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||||
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
|
go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
go.opentelemetry.io/otel v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/crypto v0.38.0 // indirect
|
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
|
golang.org/x/crypto v0.41.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||||
golang.org/x/sync v0.14.0 // indirect
|
golang.org/x/sync v0.16.0 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/sys v0.35.0 // indirect
|
||||||
golang.org/x/term v0.32.0 // indirect
|
golang.org/x/term v0.34.0 // indirect
|
||||||
golang.org/x/text v0.25.0 // indirect
|
golang.org/x/text v0.28.0 // indirect
|
||||||
golang.org/x/time v0.11.0 // indirect
|
golang.org/x/time v0.12.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
||||||
google.golang.org/api v0.230.0 // indirect
|
google.golang.org/api v0.248.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20250425173222-7b384671a197 // indirect
|
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20250721164621-a45f3dfb1074 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||||
google.golang.org/grpc v1.72.0 // indirect
|
google.golang.org/grpc v1.75.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/protobuf v1.36.8 // indirect
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/apiextensions-apiserver v0.33.0 // indirect
|
k8s.io/apiextensions-apiserver v0.34.0 // indirect
|
||||||
k8s.io/cli-runtime v0.33.0 // indirect
|
k8s.io/cli-runtime v0.34.0 // indirect
|
||||||
k8s.io/component-base v0.33.0 // indirect
|
k8s.io/component-base v0.34.0 // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
|
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
|
||||||
k8s.io/kubectl v0.33.0 // indirect
|
k8s.io/kubectl v0.34.0 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||||
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
|
sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
442
go.sum
442
go.sum
|
@ -1,27 +1,27 @@
|
||||||
c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0=
|
c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0=
|
||||||
c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w=
|
c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w=
|
||||||
cel.dev/expr v0.22.1 h1:xoFEsNh972Yzey8N9TCPx2nDvMN7TMhQEzxLuj/iRrI=
|
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
||||||
cel.dev/expr v0.22.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
|
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
cloud.google.com/go v0.120.1 h1:Z+5V7yd383+9617XDCyszmK5E4wJRJL+tquMfDj9hLM=
|
cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c=
|
||||||
cloud.google.com/go v0.120.1/go.mod h1:56Vs7sf/i2jYM6ZL9NYlC82r04PThNcPS5YgFmb0rp8=
|
cloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI=
|
||||||
cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU=
|
cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
|
||||||
cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=
|
cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
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.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA=
|
||||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw=
|
||||||
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
|
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
|
||||||
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
|
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
|
||||||
cloud.google.com/go/kms v1.21.2 h1:c/PRUSMNQ8zXrc1sdAUnsenWWaNXN+PzTXfXOcSFdoE=
|
cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk=
|
||||||
cloud.google.com/go/kms v1.21.2/go.mod h1:8wkMtHV/9Z8mLXEXr1GK7xPSBdi6knuLXIhqjuWcI6w=
|
cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8=
|
||||||
cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
|
cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
|
||||||
cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
|
cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
|
||||||
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
|
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
|
||||||
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
|
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
|
||||||
cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM=
|
cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM=
|
||||||
cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U=
|
cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U=
|
||||||
cloud.google.com/go/storage v1.51.0 h1:ZVZ11zCiD7b3k+cH5lQs/qcNaoSz3U9I0jgwVzqDlCw=
|
cloud.google.com/go/storage v1.56.0 h1:iixmq2Fse2tqxMbWhLWC9HfBj1qdxqAmiK8/eqtsLxI=
|
||||||
cloud.google.com/go/storage v1.51.0/go.mod h1:YEJfu/Ki3i5oHC/7jyTgsGZwdQ8P9hqMqvpi5kRKGgc=
|
cloud.google.com/go/storage v1.56.0/go.mod h1:Tpuj6t4NweCLzlNbw9Z9iwxEkrSem20AetIeH/shgVU=
|
||||||
cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4=
|
cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4=
|
||||||
cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI=
|
cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI=
|
||||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||||
|
@ -32,14 +32,18 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 h1:ci6Yd6nysBRLEodoziB6ah1+YOzZbZk+NYneoA6q+6E=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0/go.mod h1:QyVsSSN64v5TGltphKLQ2sQxe4OBQg0J1eKRcVBnfgE=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0 h1:MhRfI58HblXzCtWEZCO0feHs8LweePB3s90r7WaR1KU=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0/go.mod h1:kUjrAo8bgEwLeZ/CmHqNl3Z/kPm7y6FKfxxK0izYUg4=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0/go.mod h1:okZ+ZURbArNdlJ+ptXoyHNuOETzOl1Oww19rm8I2WLA=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
|
github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3 h1:ldKsKtEIblsgsr6mPwrd9yRntoX6uLz/K89wsldwx/k=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
|
github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3/go.mod h1:MAm7bk0oDLmD8yIkvfbxPW04fxzphPyL+7GzwHxOp6Y=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 h1:figxyQZXzZQIcP3njhC68bYUiTw45J8/SsHaLW8Ax0M=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0/go.mod h1:TmlMW4W5OvXOmOyKNnor8nlMMiO1ctIyzmHme/VHsrA=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w=
|
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14=
|
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI=
|
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI=
|
||||||
|
@ -51,16 +55,18 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mo
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0 h1:4LP6hvB4I5ouTbGgWtixJhgED6xdf67twf9PoY96Tbg=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0/go.mod h1:jUZ5LYlw40WMd07qxcQJD5M40aUxrfwqQX1g7zxYnrQ=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
|
||||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||||
|
@ -71,48 +77,52 @@ github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
|
github.com/aws/aws-sdk-go-v2 v1.38.3 h1:B6cV4oxnMs45fql4yRH+/Po/YU+597zgWqvDpYMturk=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
|
github.com/aws/aws-sdk-go-v2 v1.38.3/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs=
|
||||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14=
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM=
|
github.com/aws/aws-sdk-go-v2/config v1.31.6 h1:a1t8fXY4GT4xjyJExz4knbuoxSCacB5hT/WgtfPyLjo=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g=
|
github.com/aws/aws-sdk-go-v2/config v1.31.6/go.mod h1:5ByscNi7R+ztvOGzeUaIu49vkMk2soq5NaH5PYe33MQ=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=
|
github.com/aws/aws-sdk-go-v2/credentials v1.18.10 h1:xdJnXCouCx8Y0NncgoptztUocIYLKeQxrCgN6x9sdhg=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=
|
github.com/aws/aws-sdk-go-v2/credentials v1.18.10/go.mod h1:7tQk08ntj914F/5i9jC4+2HQTAuJirq7m1vZVIhEkWs=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6 h1:wbjnrrMnKew78/juW7I2BtKQwa1qlf6EjQgS69uYY14=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6/go.mod h1:AtiqqNrDioJXuUgz3+3T0mBWN7Hro2n9wll2zRUc0ww=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 h1:PcKMOZfp+kNtJTw2HF2op6SjDvwPBYRvz0Y24PQLUR4=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72 h1:PcKMOZfp+kNtJTw2HF2op6SjDvwPBYRvz0Y24PQLUR4=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72/go.mod h1:vq7/m7dahFXcdzWVOvvjasDI9RcsD3RsTfHmDundJYg=
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.72/go.mod h1:vq7/m7dahFXcdzWVOvvjasDI9RcsD3RsTfHmDundJYg=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 h1:uF68eJA6+S9iVr9WgX1NaRGyQ/6MdIyc4JNUo6TN1FA=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6/go.mod h1:qlPeVZCGPiobx8wb1ft0GHT5l+dc6ldnwInDFaMvC7Y=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 h1:pa1DEC6JoI0zduhZePp3zmhWvk/xxm4NB8Hy/Tlsgos=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6/go.mod h1:gxEjPebnhWGJoaDdtDkA0JX46VRg1wcTHYe63OfX5pE=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs=
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 h1:YyH8Hk73bYzdbvf6S8NF5z/fb/1stpiMnFSfL6jSfRA=
|
github.com/aws/aws-sdk-go-v2/service/ecr v1.50.1 h1:lcwFjRx3C/hBxJzoWkD6DIG2jeB+mzLmFVBFVOadxxE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3/go.mod h1:iQ1skgw1XRK+6Lgkb0I9ODatAP72WoTILh0zXQ5DtbU=
|
github.com/aws/aws-sdk-go-v2/service/ecr v1.50.1/go.mod h1:qt9OL5kXqWoSub4QAkOF74mS3M2zOTNxMODqgwEUjt8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
|
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2 h1:EfatDVSMFxaS5TiR0C0zssQU1Nm+rGx3VbUGIH1y274=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
|
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2/go.mod h1:oRy1IEgzXtOkEk4B/J7HZbXUC258drDLtkmc++lN7IA=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/eks v1.73.1 h1:Txq5jxY/ao+2Vx/kX9+65WTqkzCnxSlXnwIj+Cr/fng=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/eks v1.73.1/go.mod h1:+hYFg3laewH0YCfJRv+o5R3bradDKmFIm/uaiaD1U7U=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM=
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 h1:lguz0bmOoGzozP9XfRJR1QIayEYo+2vP/No3OfLF0pU=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 h1:lguz0bmOoGzozP9XfRJR1QIayEYo+2vP/No3OfLF0pU=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 h1:LHS1YAIJXJ4K9zS+1d/xa9JAA9sL2QyXIQCQFQW/X08=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6/go.mod h1:c9PCiTEuh0wQID5/KqA32J+HAgZxN9tOGXKCiYJjTZI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA=
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 h1:RivOtUH3eEu6SWnUMFHKAW4MqDOzWn1vGQ3S38Y5QMg=
|
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3 h1:RivOtUH3eEu6SWnUMFHKAW4MqDOzWn1vGQ3S38Y5QMg=
|
||||||
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3/go.mod h1:cQn6tAF77Di6m4huxovNM7NVAozWTZLsDRp9t8Z/WYk=
|
github.com/aws/aws-sdk-go-v2/service/kms v1.38.3/go.mod h1:cQn6tAF77Di6m4huxovNM7NVAozWTZLsDRp9t8Z/WYk=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 h1:tWUG+4wZqdMl/znThEk9tcCy8tTMxq8dW0JTgamohrY=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 h1:tWUG+4wZqdMl/znThEk9tcCy8tTMxq8dW0JTgamohrY=
|
||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2/go.mod h1:U5SNqwhXB3Xe6F47kXvWihPl/ilGaEDe8HD/50Z9wxc=
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2/go.mod h1:U5SNqwhXB3Xe6F47kXvWihPl/ilGaEDe8HD/50Z9wxc=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 h1:8OLZnVJPvjnrxEwHFg9hVUof/P4sibH+Ea4KKuqAGSg=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.29.1/go.mod h1:27M3BpVi0C02UiQh1w9nsBEit6pLhlaH3NHna6WUbDE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 h1:gKWSTnqudpo8dAxqBqZnDoDWCiEh/40FziUjr/mo6uA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2/go.mod h1:x7+rkNmRoEN1U13A6JE2fXne9EWyJy54o3n6d4mGaXQ=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 h1:YZPjhyaGzhDQEvsffDEcpycq49nl7fiGcfJTIo8BszI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.38.2/go.mod h1:2dIN8qhQfv37BdUYGgEC8Q3tteM3zFxTI1MLO2O3J3c=
|
||||||
github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=
|
github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
|
||||||
github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||||
|
@ -127,15 +137,16 @@ github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnT
|
||||||
github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
||||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k=
|
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls=
|
||||||
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||||
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
|
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
|
||||||
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
||||||
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
|
github.com/coreos/go-oidc/v3 v3.15.0 h1:R6Oz8Z4bqWR7VFQ+sPSvZPQv4x8M+sJkDO5ojgwlyAg=
|
||||||
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
github.com/coreos/go-oidc/v3 v3.15.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||||
|
@ -144,16 +155,14 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
|
||||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||||
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
||||||
github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k=
|
github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo=
|
||||||
github.com/docker/cli v28.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/docker v28.1.1+incompatible h1:49M11BFLsVO1gxY9UX9p/zwkE/rswggs8AdFmXQw51I=
|
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
||||||
github.com/docker/docker v28.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
|
@ -178,42 +187,42 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.13 h1:2X5yjz/rk9mg7+bMFBDZKGKzeZpAmY2s6iwbNZz7OzM=
|
github.com/fluxcd/cli-utils v0.36.0-flux.15 h1:Et5QLnIpRjj+oZtM9gEybkAaoNsjysHq0y1253Ai94Y=
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.13/go.mod h1:b2iSoIeDTtjfCB0IKtGgqlhhvWa1oux3e90CjOf81oA=
|
github.com/fluxcd/cli-utils v0.36.0-flux.15/go.mod h1:AqRUmWIfNE7cdL6NWSGF0bAlypGs+9x5UQ2qOtlEzv4=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0=
|
github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ=
|
github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
|
||||||
github.com/fluxcd/pkg/apis/event v0.17.0 h1:foEINE++pCJlWVhWjYDXfkVmGKu8mQ4BDBlbYi5NU7M=
|
github.com/fluxcd/pkg/apis/event v0.19.0 h1:ZJU2voontkzp5rNYA4JMOu40S4tRcrWi4Do59EnyFwg=
|
||||||
github.com/fluxcd/pkg/apis/event v0.17.0/go.mod h1:0fLhLFiHlRTDKPDXdRnv+tS7mCMIQ0fJxnEfmvGM/5A=
|
github.com/fluxcd/pkg/apis/event v0.19.0/go.mod h1:deuIyUb6lh+Z1Ccvwwxhm1wNM3kpSo+vF1IgRnpaZfQ=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.10.0 h1:47EeSzkQvlQZdH92vHMe2lK2iR8aOSEJq95avw5idts=
|
github.com/fluxcd/pkg/apis/kustomize v1.12.0 h1:KvZN6xwgP/dNSeckL4a/Uv715XqiN1C3xS+jGcPejtE=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v1.10.0/go.mod h1:UsqMV4sqNa1Yg0pmTsdkHRJr7bafBOENIJoAN+3ezaQ=
|
github.com/fluxcd/pkg/apis/kustomize v1.12.0/go.mod h1:OojLxIdKm1JAAdh3sL4j4F+vfrLKb7kq1vr8bpyEKgg=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg=
|
github.com/fluxcd/pkg/apis/meta v1.21.0 h1:R+bN02chcs0HUmyVDQhqe/FHmYLjipVDMLnyYfNX850=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
|
github.com/fluxcd/pkg/apis/meta v1.21.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
|
||||||
github.com/fluxcd/pkg/auth v0.16.0 h1:YEjSaNqlpYoXfoFAGhU/Z8y0322nGsT24W6zCh+sbGw=
|
github.com/fluxcd/pkg/auth v0.30.0 h1:7JMnY1ClArvOsadt6hOxceu8Q2hLsYHFMt0DV3BQl4Q=
|
||||||
github.com/fluxcd/pkg/auth v0.16.0/go.mod h1:+BRnAO61Nr6fACEjJS6eNRdOk1nXhX/FCPylYn1ypNc=
|
github.com/fluxcd/pkg/auth v0.30.0/go.mod h1:me38o1nDfSLw6YvnkT9Ce/zqJZICZSA7j5pNMR3JUbc=
|
||||||
github.com/fluxcd/pkg/cache v0.9.0 h1:EGKfOLMG3fOwWnH/4Axl5xd425mxoQbZzlZoLfd8PDk=
|
github.com/fluxcd/pkg/cache v0.11.0 h1:fsE8S+una21fSNw4MDXGUIf0Gf1J+pqa4RbsVKf2aTI=
|
||||||
github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU=
|
github.com/fluxcd/pkg/cache v0.11.0/go.mod h1:2RTIU6PsJniHmfnllQWFEo7fa5V8KQlnMgn4o0sme40=
|
||||||
github.com/fluxcd/pkg/envsubst v1.4.0 h1:pYsb6wrmXOSfHXuXQHaaBBMt3LumhgCb8SMdBNAwV/U=
|
github.com/fluxcd/pkg/envsubst v1.5.0 h1:S07mo+MkGhptdHA4pRze5HPKlc8tHxKswNdcMZi1WDY=
|
||||||
github.com/fluxcd/pkg/envsubst v1.4.0/go.mod h1:zSDFO3Wawi+vI2NPxsMQp+EkIsz/85MNg/s1Wzmqt+s=
|
github.com/fluxcd/pkg/envsubst v1.5.0/go.mod h1:c3a8DYI855sZUubHFYQbjfjop6Wu4/zg1cLyf7SnCes=
|
||||||
github.com/fluxcd/pkg/http/fetch v0.16.0 h1:XzhBTSK5HNdAPEnEGMJHwtoN2LfqQ9QFDsu3DGzl908=
|
github.com/fluxcd/pkg/http/fetch v0.19.0 h1:dRdErv8X2t/VKnh5kFRZrlqKzbq9Gh0n/z3XArjdLho=
|
||||||
github.com/fluxcd/pkg/http/fetch v0.16.0/go.mod h1:+A+yrOzwA5436ufD8NPeCCQFNzk4metoPUgRVCozvzw=
|
github.com/fluxcd/pkg/http/fetch v0.19.0/go.mod h1:z32w8nezoBvQfMogCkhAoqKToOZzPSbIW0PeN2fKXqA=
|
||||||
github.com/fluxcd/pkg/kustomize v1.18.0 h1:wWK+qYwmBmba3N3VAqZ9ijnfVGGaIjcaHWo033URZTw=
|
github.com/fluxcd/pkg/kustomize v1.21.0 h1:J+OcRTBWJcOwqhNW2oZyPHN7u54qBpScYLYnqTiM3gE=
|
||||||
github.com/fluxcd/pkg/kustomize v1.18.0/go.mod h1:Ij9722MdWIE6B1EPg2ZJUf6npycgfRfN4Lohi7D/Kic=
|
github.com/fluxcd/pkg/kustomize v1.21.0/go.mod h1:drVtmqUCJc/0a178vjl67DSePQahOBI+aO4x1kzV13M=
|
||||||
github.com/fluxcd/pkg/runtime v0.60.0 h1:d++EkV3FlycB+bzakB5NumwY4J8xts8i7lbvD6jBLeU=
|
github.com/fluxcd/pkg/runtime v0.83.0 h1:XzpwKzo7GqfBE/BKpxG5B4U7cUnojnB407S9Dpp6oLU=
|
||||||
github.com/fluxcd/pkg/runtime v0.60.0/go.mod h1:UeU0/eZLErYC/1bTmgzBfNXhiHy9fuQzjfLK0HxRgxY=
|
github.com/fluxcd/pkg/runtime v0.83.0/go.mod h1:r8KLvXRguKtpLAa66fA19rIbwPViXm8az038IUabYvw=
|
||||||
github.com/fluxcd/pkg/sourceignore v0.12.0 h1:jCIe6d50rQ3wdXPF0+PhhqN0XrTRIq3upMomPelI8Mw=
|
github.com/fluxcd/pkg/sourceignore v0.14.0 h1:ZiZzbXtXb/Qp7I7JCStsxOlX8ri8rWwCvmvIrJ0UzQQ=
|
||||||
github.com/fluxcd/pkg/sourceignore v0.12.0/go.mod h1:dc0zvkuXM5OgL/b3IkrVuwvPjj1zJn4NBUMH45uJ4Y0=
|
github.com/fluxcd/pkg/sourceignore v0.14.0/go.mod h1:E3zKvyTyB+oQKqm/2I/jS6Rrt3B7fNuig/4bY2vi3bg=
|
||||||
github.com/fluxcd/pkg/ssa v0.48.0 h1:DW+4DG8L/yZEi30UltOEXPB1d/ZFn4HfVhpJQp5oc2o=
|
github.com/fluxcd/pkg/ssa v0.53.0 h1:EtKFAYWXohIGkzPhIrv8NbV5zYr4iZHY6DaNxMR9+bU=
|
||||||
github.com/fluxcd/pkg/ssa v0.48.0/go.mod h1:T50TO0U2obLodZnrFgOrxollfBEy4V673OkM2aTUF1c=
|
github.com/fluxcd/pkg/ssa v0.53.0/go.mod h1:0IZxnnH8XkDkFzWjoMJsFEwPIWPOk3Gc/WR5+gT/KgI=
|
||||||
github.com/fluxcd/pkg/tar v0.12.0 h1:og6F+ivnWNRbNJSq0ukCTVs7YrGIlzjxSVZU+E8NprM=
|
github.com/fluxcd/pkg/tar v0.14.0 h1:9Gku8FIvPt2bixKldZnzXJ/t+7SloxePlzyVGOK8GVQ=
|
||||||
github.com/fluxcd/pkg/tar v0.12.0/go.mod h1:Ra5Cj++MD5iCy7bZGKJJX3GpOeMPv+ZDkPO9bBwpDeU=
|
github.com/fluxcd/pkg/tar v0.14.0/go.mod h1:+rOWYk93qLEJ8WwmkvJOkB8i0dna1mrwJFybE8i9Udo=
|
||||||
github.com/fluxcd/pkg/testserver v0.11.0 h1:a/kxpFqv7XQxZjwVPP3voooRmSd/3ipLVolK0xUIxXQ=
|
github.com/fluxcd/pkg/testserver v0.13.0 h1:xEpBcEYtD7bwvZ+i0ZmChxKkDo/wfQEV3xmnzVybSSg=
|
||||||
github.com/fluxcd/pkg/testserver v0.11.0/go.mod h1:E8LAH1jW9uClFjTRN27Y/gCCSrzNVx1/w/0NxKuNcas=
|
github.com/fluxcd/pkg/testserver v0.13.0/go.mod h1:akRYv3FLQUsme15na9ihECRG6hBuqni4XEY9W8kzs8E=
|
||||||
github.com/fluxcd/source-controller/api v1.6.0 h1:IxfjUczJ2pzbXIef6iQ0RHEH4AYA9anJfTGK8dzwODM=
|
github.com/fluxcd/source-controller/api v1.7.0-rc.3 h1:+9cd//77LAgp0XRe97CXUaPnu78jsRNWTXq95GHGhgc=
|
||||||
github.com/fluxcd/source-controller/api v1.6.0/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
|
github.com/fluxcd/source-controller/api v1.7.0-rc.3/go.mod h1:sbJibK4Ik+2AuTRRLXPA+n2u6nLUIGaxC07ava+RqeM=
|
||||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
|
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||||
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e h1:y/1nzrdF+RPds4lfoEpNhjfmzlgZtPqyO3jMzrqDQws=
|
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e h1:y/1nzrdF+RPds4lfoEpNhjfmzlgZtPqyO3jMzrqDQws=
|
||||||
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e/go.mod h1:awFzISqLJoZLm+i9QQ4SgMNHDqljH6jWV0B36V5MrUM=
|
github.com/getsops/gopgagent v0.0.0-20241224165529-7044f28e491e/go.mod h1:awFzISqLJoZLm+i9QQ4SgMNHDqljH6jWV0B36V5MrUM=
|
||||||
github.com/getsops/sops/v3 v3.10.2 h1:7t7lBXFcXJPsDMrpYoI36r8xIhjWUmEc8Qdjuwyo+WY=
|
github.com/getsops/sops/v3 v3.10.2 h1:7t7lBXFcXJPsDMrpYoI36r8xIhjWUmEc8Qdjuwyo+WY=
|
||||||
|
@ -224,13 +233,13 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66D
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||||
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
|
github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
|
||||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||||
github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ=
|
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
||||||
github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
|
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
|
||||||
github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw=
|
github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA=
|
||||||
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.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||||
|
@ -247,32 +256,32 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
|
github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
|
||||||
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||||
github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4=
|
github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ=
|
||||||
github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo=
|
github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
|
||||||
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
|
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||||
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
|
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI=
|
github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
|
||||||
github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI=
|
github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
|
||||||
github.com/google/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/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc=
|
github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc=
|
||||||
github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0=
|
github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0=
|
||||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
|
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ=
|
||||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||||
github.com/google/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/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||||
|
@ -281,8 +290,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||||
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
||||||
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
|
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||||
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 h1:Y9iQJfEqnN3/Nce9cOegemcy/9Ai5k3huT6E80F3zaw=
|
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 h1:Y9iQJfEqnN3/Nce9cOegemcy/9Ai5k3huT6E80F3zaw=
|
||||||
|
@ -298,8 +307,8 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1
|
||||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=
|
github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM=
|
||||||
|
@ -308,10 +317,10 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9
|
||||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
|
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
|
||||||
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
|
github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw=
|
||||||
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
|
github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
|
||||||
github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4=
|
github.com/hashicorp/vault/api v1.20.0 h1:KQMHElgudOsr+IbJgmbjHnCTxEpKs9LnozA1D3nozU4=
|
||||||
github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA=
|
github.com/hashicorp/vault/api v1.20.0/go.mod h1:GZ4pcjfzoOWpkJ3ijHNpEoAxKEsBJnVljyTe3jM2Sms=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
|
@ -361,18 +370,19 @@ github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFL
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
github.com/onsi/ginkgo/v2 v2.25.2 h1:hepmgwx1D+llZleKQDMEvy8vIlCxMGt7W5ZxDjIEhsw=
|
||||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
github.com/onsi/ginkgo/v2 v2.25.2/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
|
||||||
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
|
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||||
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||||
github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be h1:f2PlhC9pm5sqpBZFvnAoKj+KzXRzbjFMA+TqXfJdgho=
|
github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be h1:f2PlhC9pm5sqpBZFvnAoKj+KzXRzbjFMA+TqXfJdgho=
|
||||||
github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/go-digest/blake3 v0.0.0-20250116041648-1e56c6daea3b h1:nAiL9bmUK4IzFrKoVMRykv0iYGdoit5vpbPaVCZ+fI4=
|
github.com/opencontainers/go-digest/blake3 v0.0.0-20250116041648-1e56c6daea3b h1:nAiL9bmUK4IzFrKoVMRykv0iYGdoit5vpbPaVCZ+fI4=
|
||||||
|
@ -398,16 +408,14 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
||||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
||||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||||
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
|
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
||||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
||||||
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
|
|
||||||
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
|
|
||||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
@ -420,8 +428,9 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||||
|
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=
|
github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=
|
||||||
github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=
|
github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=
|
||||||
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||||
|
@ -439,8 +448,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ=
|
github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ=
|
||||||
github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po=
|
github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
|
@ -466,24 +475,24 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||||
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA=
|
go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs=
|
||||||
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
|
go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
||||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc=
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw=
|
||||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
||||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
||||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
||||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
||||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
||||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
@ -492,11 +501,15 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
@ -505,15 +518,15 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -521,40 +534,42 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||||
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
|
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||||
google.golang.org/api v0.230.0 h1:2u1hni3E+UXAXrONrrkfWpi/V6cyKVAbfGVeGtC3OxM=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
google.golang.org/api v0.230.0/go.mod h1:aqvtoMk7YkiXx+6U12arQFExiRV9D/ekvMCwCd/TksQ=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/genproto v0.0.0-20250425173222-7b384671a197 h1:qWb9n6MA4nHA/g2varvEG/jTCs8zUuSa+5VqFgX2K+0=
|
google.golang.org/api v0.248.0 h1:hUotakSkcwGdYUqzCRc5yGYsg4wXxpkKlW5ryVqvC1Y=
|
||||||
google.golang.org/genproto v0.0.0-20250425173222-7b384671a197/go.mod h1:Cej/8iHf9mPl71o/a+R1rrvSFrAAVCUFX9s/sbNttBc=
|
google.golang.org/api v0.248.0/go.mod h1:yAFUAF56Li7IuIQbTFoLwXTCI6XCFKueOlS7S9e4F9k=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197 h1:9DuBh3k1jUho2DHdxH+kbJwthIAq02vGvZNrD2ggF+Y=
|
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250425173222-7b384671a197/go.mod h1:Cd8IzgPo5Akum2c9R6FsXNaZbH3Jpa2gpHlW89FqlyQ=
|
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197 h1:29cjnHVylHwTzH66WfFZqgSQgnxzvWE+jvBwpZCLRxY=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250721164621-a45f3dfb1074 h1:mVXdvnmR3S3BQOqHECm9NGMjYiRtEvDYcqAqedTXY6s=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250425173222-7b384671a197/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250721164621-a45f3dfb1074/go.mod h1:vYFwMYFbmA8vl6Z/krj/h7+U/AqpHknwJX4Uqgfyc7I=
|
||||||
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE=
|
||||||
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||||
|
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||||
|
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
@ -571,38 +586,41 @@ 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.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||||
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
|
k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
|
||||||
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
|
k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
|
||||||
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs=
|
k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc=
|
||||||
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc=
|
k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0=
|
||||||
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
|
k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
|
||||||
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||||
k8s.io/cli-runtime v0.33.0 h1:Lbl/pq/1o8BaIuyn+aVLdEPHVN665tBAXUePs8wjX7c=
|
k8s.io/cli-runtime v0.34.0 h1:N2/rUlJg6TMEBgtQ3SDRJwa8XyKUizwjlOknT1mB2Cw=
|
||||||
k8s.io/cli-runtime v0.33.0/go.mod h1:QcA+r43HeUM9jXFJx7A+yiTPfCooau/iCcP1wQh4NFw=
|
k8s.io/cli-runtime v0.34.0/go.mod h1:t/skRecS73Piv+J+FmWIQA2N2/rDjdYSQzEE67LUUs8=
|
||||||
k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98=
|
k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo=
|
||||||
k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg=
|
k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY=
|
||||||
k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk=
|
k8s.io/component-base v0.34.0 h1:bS8Ua3zlJzapklsB1dZgjEJuJEeHjj8yTu1gxE2zQX8=
|
||||||
k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU=
|
k8s.io/component-base v0.34.0/go.mod h1:RSCqUdvIjjrEm81epPcjQ/DS+49fADvGSCkIP3IC6vg=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
|
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
|
||||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
|
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
|
||||||
k8s.io/kubectl v0.33.0 h1:HiRb1yqibBSCqic4pRZP+viiOBAnIdwYDpzUFejs07g=
|
k8s.io/kubectl v0.34.0 h1:NcXz4TPTaUwhiX4LU+6r6udrlm0NsVnSkP3R9t0dmxs=
|
||||||
k8s.io/kubectl v0.33.0/go.mod h1:gAlGBuS1Jq1fYZ9AjGWbI/5Vk3M/VW2DK4g10Fpyn/0=
|
k8s.io/kubectl v0.34.0/go.mod h1:bmd0W5i+HuG7/p5sqicr0Li0rR2iIhXL0oUyLF3OjR4=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
|
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
|
sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
|
sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||||
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
|
sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I=
|
||||||
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o=
|
sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA=
|
sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY=
|
sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po=
|
||||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
||||||
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||||
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
|
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2023 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -14,15 +14,17 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package intcache
|
package cache
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
OperationFetchKubeConfig = "fetch_kubeconfig"
|
||||||
OperationDecryptWithAWS = "decrypt_with_aws"
|
OperationDecryptWithAWS = "decrypt_with_aws"
|
||||||
OperationDecryptWithAzure = "decrypt_with_azure"
|
OperationDecryptWithAzure = "decrypt_with_azure"
|
||||||
OperationDecryptWithGCP = "decrypt_with_gcp"
|
OperationDecryptWithGCP = "decrypt_with_gcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AllOperations = []string{
|
var AllOperations = []string{
|
||||||
|
OperationFetchKubeConfig,
|
||||||
OperationDecryptWithAWS,
|
OperationDecryptWithAWS,
|
||||||
OperationDecryptWithAzure,
|
OperationDecryptWithAzure,
|
||||||
OperationDecryptWithGCP,
|
OperationDecryptWithGCP,
|
||||||
|
|
|
@ -16,4 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
const OCIArtifactOriginRevisionAnnotation = "org.opencontainers.image.revision"
|
const (
|
||||||
|
OCIArtifactOriginRevisionAnnotation = "org.opencontainers.image.revision"
|
||||||
|
TerminalErrorMessage = "Reconciliation failed terminally due to configuration error"
|
||||||
|
)
|
||||||
|
|
|
@ -90,7 +90,7 @@ stringData:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -120,6 +120,7 @@ stringData:
|
||||||
|
|
||||||
t.Run("fails to reconcile from cross-namespace source", func(t *testing.T) {
|
t.Run("fails to reconcile from cross-namespace source", func(t *testing.T) {
|
||||||
reconciler.NoCrossNamespaceRefs = true
|
reconciler.NoCrossNamespaceRefs = true
|
||||||
|
defer func() { reconciler.NoCrossNamespaceRefs = false }()
|
||||||
|
|
||||||
revision = "v2.0.0"
|
revision = "v2.0.0"
|
||||||
err = applyGitRepository(repositoryName, artifact, revision)
|
err = applyGitRepository(repositoryName, artifact, revision)
|
||||||
|
@ -132,5 +133,6 @@ stringData:
|
||||||
}, timeout, time.Second).Should(BeTrue())
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
g.Expect(readyCondition.Reason).To(Equal(apiacl.AccessDeniedReason))
|
g.Expect(readyCondition.Reason).To(Equal(apiacl.AccessDeniedReason))
|
||||||
|
g.Expect(apimeta.IsStatusConditionTrue(resultK.Status.Conditions, meta.StalledCondition)).Should(BeTrue())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,8 @@ data: {}
|
||||||
t.Run("object level workload identity feature gate enabled", func(t *testing.T) {
|
t.Run("object level workload identity feature gate enabled", func(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
t.Setenv(auth.EnvVarEnableObjectLevelWorkloadIdentity, "true")
|
auth.EnableObjectLevelWorkloadIdentity()
|
||||||
|
t.Cleanup(auth.DisableObjectLevelWorkloadIdentity)
|
||||||
|
|
||||||
kustomizationKey := types.NamespacedName{
|
kustomizationKey := types.NamespacedName{
|
||||||
Name: fmt.Sprintf("invalid-config-%s", randStringRunes(5)),
|
Name: fmt.Sprintf("invalid-config-%s", randStringRunes(5)),
|
||||||
|
|
|
@ -22,11 +22,12 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
securejoin "github.com/cyphar/filepath-securejoin"
|
securejoin "github.com/cyphar/filepath-securejoin"
|
||||||
|
celtypes "github.com/google/cel-go/common/types"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||||
|
@ -36,14 +37,9 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
kerrors "k8s.io/apimachinery/pkg/util/errors"
|
kerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
kuberecorder "k8s.io/client-go/tools/record"
|
kuberecorder "k8s.io/client-go/tools/record"
|
||||||
"k8s.io/client-go/util/workqueue"
|
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/builder"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
"github.com/fluxcd/cli-utils/pkg/kstatus/polling"
|
"github.com/fluxcd/cli-utils/pkg/kstatus/polling"
|
||||||
|
@ -53,6 +49,7 @@ import (
|
||||||
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
|
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
"github.com/fluxcd/pkg/auth"
|
"github.com/fluxcd/pkg/auth"
|
||||||
|
authutils "github.com/fluxcd/pkg/auth/utils"
|
||||||
"github.com/fluxcd/pkg/cache"
|
"github.com/fluxcd/pkg/cache"
|
||||||
"github.com/fluxcd/pkg/http/fetch"
|
"github.com/fluxcd/pkg/http/fetch"
|
||||||
generator "github.com/fluxcd/pkg/kustomize"
|
generator "github.com/fluxcd/pkg/kustomize"
|
||||||
|
@ -63,7 +60,6 @@ import (
|
||||||
runtimeCtrl "github.com/fluxcd/pkg/runtime/controller"
|
runtimeCtrl "github.com/fluxcd/pkg/runtime/controller"
|
||||||
"github.com/fluxcd/pkg/runtime/jitter"
|
"github.com/fluxcd/pkg/runtime/jitter"
|
||||||
"github.com/fluxcd/pkg/runtime/patch"
|
"github.com/fluxcd/pkg/runtime/patch"
|
||||||
"github.com/fluxcd/pkg/runtime/predicates"
|
|
||||||
"github.com/fluxcd/pkg/runtime/statusreaders"
|
"github.com/fluxcd/pkg/runtime/statusreaders"
|
||||||
"github.com/fluxcd/pkg/ssa"
|
"github.com/fluxcd/pkg/ssa"
|
||||||
"github.com/fluxcd/pkg/ssa/normalize"
|
"github.com/fluxcd/pkg/ssa/normalize"
|
||||||
|
@ -74,7 +70,9 @@ import (
|
||||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
intcache "github.com/fluxcd/kustomize-controller/internal/cache"
|
intcache "github.com/fluxcd/kustomize-controller/internal/cache"
|
||||||
"github.com/fluxcd/kustomize-controller/internal/decryptor"
|
"github.com/fluxcd/kustomize-controller/internal/decryptor"
|
||||||
|
"github.com/fluxcd/kustomize-controller/internal/features"
|
||||||
"github.com/fluxcd/kustomize-controller/internal/inventory"
|
"github.com/fluxcd/kustomize-controller/internal/inventory"
|
||||||
|
intruntime "github.com/fluxcd/kustomize-controller/internal/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// +kubebuilder:rbac:groups=kustomize.toolkit.fluxcd.io,resources=kustomizations,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=kustomize.toolkit.fluxcd.io,resources=kustomizations,verbs=get;list;watch;create;update;patch;delete
|
||||||
|
@ -92,85 +90,37 @@ type KustomizationReconciler struct {
|
||||||
kuberecorder.EventRecorder
|
kuberecorder.EventRecorder
|
||||||
runtimeCtrl.Metrics
|
runtimeCtrl.Metrics
|
||||||
|
|
||||||
artifactFetchRetries int
|
// Kubernetes options
|
||||||
requeueDependency time.Duration
|
|
||||||
|
|
||||||
Mapper apimeta.RESTMapper
|
APIReader client.Reader
|
||||||
APIReader client.Reader
|
ClusterReader engine.ClusterReaderFactory
|
||||||
ClusterReader engine.ClusterReaderFactory
|
ConcurrentSSA int
|
||||||
ControllerName string
|
ControllerName string
|
||||||
statusManager string
|
KubeConfigOpts runtimeClient.KubeConfigOptions
|
||||||
|
Mapper apimeta.RESTMapper
|
||||||
|
StatusManager string
|
||||||
|
|
||||||
|
// Multi-tenancy and security options
|
||||||
|
|
||||||
|
DefaultServiceAccount string
|
||||||
|
DisallowedFieldManagers []string
|
||||||
NoCrossNamespaceRefs bool
|
NoCrossNamespaceRefs bool
|
||||||
NoRemoteBases bool
|
NoRemoteBases bool
|
||||||
FailFast bool
|
SOPSAgeSecret string
|
||||||
DefaultServiceAccount string
|
|
||||||
KubeConfigOpts runtimeClient.KubeConfigOptions
|
|
||||||
ConcurrentSSA int
|
|
||||||
DisallowedFieldManagers []string
|
|
||||||
StrictSubstitutions bool
|
|
||||||
GroupChangeLog bool
|
|
||||||
TokenCache *cache.TokenCache
|
TokenCache *cache.TokenCache
|
||||||
}
|
|
||||||
|
|
||||||
// KustomizationReconcilerOptions contains options for the KustomizationReconciler.
|
// Retry and requeue options
|
||||||
type KustomizationReconcilerOptions struct {
|
|
||||||
HTTPRetry int
|
ArtifactFetchRetries int
|
||||||
DependencyRequeueInterval time.Duration
|
DependencyRequeueInterval time.Duration
|
||||||
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *KustomizationReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, opts KustomizationReconcilerOptions) error {
|
// Feature gates
|
||||||
const (
|
|
||||||
ociRepositoryIndexKey string = ".metadata.ociRepository"
|
|
||||||
gitRepositoryIndexKey string = ".metadata.gitRepository"
|
|
||||||
bucketIndexKey string = ".metadata.bucket"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Index the Kustomizations by the OCIRepository references they (may) point at.
|
AdditiveCELDependencyCheck bool
|
||||||
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, ociRepositoryIndexKey,
|
AllowExternalArtifact bool
|
||||||
r.indexBy(sourcev1.OCIRepositoryKind)); err != nil {
|
FailFast bool
|
||||||
return fmt.Errorf("failed setting index fields: %w", err)
|
GroupChangeLog bool
|
||||||
}
|
StrictSubstitutions bool
|
||||||
|
|
||||||
// Index the Kustomizations by the GitRepository references they (may) point at.
|
|
||||||
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, gitRepositoryIndexKey,
|
|
||||||
r.indexBy(sourcev1.GitRepositoryKind)); err != nil {
|
|
||||||
return fmt.Errorf("failed setting index fields: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Index the Kustomizations by the Bucket references they (may) point at.
|
|
||||||
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, bucketIndexKey,
|
|
||||||
r.indexBy(sourcev1.BucketKind)); err != nil {
|
|
||||||
return fmt.Errorf("failed setting index fields: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.requeueDependency = opts.DependencyRequeueInterval
|
|
||||||
r.statusManager = fmt.Sprintf("gotk-%s", r.ControllerName)
|
|
||||||
r.artifactFetchRetries = opts.HTTPRetry
|
|
||||||
|
|
||||||
return ctrl.NewControllerManagedBy(mgr).
|
|
||||||
For(&kustomizev1.Kustomization{}, builder.WithPredicates(
|
|
||||||
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
|
|
||||||
)).
|
|
||||||
Watches(
|
|
||||||
&sourcev1.OCIRepository{},
|
|
||||||
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(ociRepositoryIndexKey)),
|
|
||||||
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
|
||||||
).
|
|
||||||
Watches(
|
|
||||||
&sourcev1.GitRepository{},
|
|
||||||
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(gitRepositoryIndexKey)),
|
|
||||||
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
|
||||||
).
|
|
||||||
Watches(
|
|
||||||
&sourcev1.Bucket{},
|
|
||||||
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(bucketIndexKey)),
|
|
||||||
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
|
||||||
).
|
|
||||||
WithOptions(controller.Options{
|
|
||||||
RateLimiter: opts.RateLimiter,
|
|
||||||
}).
|
|
||||||
Complete(r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) {
|
func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) {
|
||||||
|
@ -236,17 +186,15 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
// Configure custom health checks.
|
// Configure custom health checks.
|
||||||
statusReaders, err := cel.PollerWithCustomHealthChecks(ctx, obj.Spec.HealthCheckExprs)
|
statusReaders, err := cel.PollerWithCustomHealthChecks(ctx, obj.Spec.HealthCheckExprs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
const msg = "Reconciliation failed terminally due to configuration error"
|
errMsg := fmt.Sprintf("%s: %v", TerminalErrorMessage, err)
|
||||||
errMsg := fmt.Sprintf("%s: %v", msg, err)
|
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.InvalidCELExpressionReason, "%s", errMsg)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.InvalidCELExpressionReason, "%s", errMsg)
|
||||||
conditions.MarkStalled(obj, meta.InvalidCELExpressionReason, "%s", errMsg)
|
conditions.MarkStalled(obj, meta.InvalidCELExpressionReason, "%s", errMsg)
|
||||||
obj.Status.ObservedGeneration = obj.Generation
|
obj.Status.ObservedGeneration = obj.Generation
|
||||||
log.Error(err, msg)
|
|
||||||
r.event(obj, "", "", eventv1.EventSeverityError, errMsg, nil)
|
r.event(obj, "", "", eventv1.EventSeverityError, errMsg, nil)
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, reconcile.TerminalError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check object-level workload identity feature gate.
|
// Check object-level workload identity feature gate and decryption with service account.
|
||||||
if d := obj.Spec.Decryption; d != nil && d.ServiceAccountName != "" && !auth.IsObjectLevelWorkloadIdentityEnabled() {
|
if d := obj.Spec.Decryption; d != nil && d.ServiceAccountName != "" && !auth.IsObjectLevelWorkloadIdentityEnabled() {
|
||||||
const gate = auth.FeatureGateObjectLevelWorkloadIdentity
|
const gate = auth.FeatureGateObjectLevelWorkloadIdentity
|
||||||
const msgFmt = "to use spec.decryption.serviceAccountName for decryption authentication please enable the %s feature gate in the controller"
|
const msgFmt = "to use spec.decryption.serviceAccountName for decryption authentication please enable the %s feature gate in the controller"
|
||||||
|
@ -271,9 +219,9 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
|
|
||||||
if acl.IsAccessDenied(err) {
|
if acl.IsAccessDenied(err) {
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, apiacl.AccessDeniedReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, apiacl.AccessDeniedReason, "%s", err)
|
||||||
log.Error(err, "Access denied to cross-namespace source")
|
conditions.MarkStalled(obj, apiacl.AccessDeniedReason, "%s", err)
|
||||||
r.event(obj, "", "", eventv1.EventSeverityError, err.Error(), nil)
|
r.event(obj, "", "", eventv1.EventSeverityError, err.Error(), nil)
|
||||||
return ctrl.Result{RequeueAfter: obj.GetRetryInterval()}, nil
|
return ctrl.Result{}, reconcile.TerminalError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retry with backoff on transient errors.
|
// Retry with backoff on transient errors.
|
||||||
|
@ -282,10 +230,10 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
|
|
||||||
// Requeue the reconciliation if the source artifact is not found.
|
// Requeue the reconciliation if the source artifact is not found.
|
||||||
if artifactSource.GetArtifact() == nil {
|
if artifactSource.GetArtifact() == nil {
|
||||||
msg := fmt.Sprintf("Source artifact not found, retrying in %s", r.requeueDependency.String())
|
msg := fmt.Sprintf("Source artifact not found, retrying in %s", r.DependencyRequeueInterval.String())
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ArtifactFailedReason, "%s", msg)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ArtifactFailedReason, "%s", msg)
|
||||||
log.Info(msg)
|
log.Info(msg)
|
||||||
return ctrl.Result{RequeueAfter: r.requeueDependency}, nil
|
return ctrl.Result{RequeueAfter: r.DependencyRequeueInterval}, nil
|
||||||
}
|
}
|
||||||
revision := artifactSource.GetArtifact().Revision
|
revision := artifactSource.GetArtifact().Revision
|
||||||
originRevision := getOriginRevision(artifactSource)
|
originRevision := getOriginRevision(artifactSource)
|
||||||
|
@ -293,11 +241,22 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
// Check dependencies and requeue the reconciliation if the check fails.
|
// Check dependencies and requeue the reconciliation if the check fails.
|
||||||
if len(obj.Spec.DependsOn) > 0 {
|
if len(obj.Spec.DependsOn) > 0 {
|
||||||
if err := r.checkDependencies(ctx, obj, artifactSource); err != nil {
|
if err := r.checkDependencies(ctx, obj, artifactSource); err != nil {
|
||||||
|
// Check if this is a terminal error that should not trigger retries
|
||||||
|
if errors.Is(err, reconcile.TerminalError(nil)) {
|
||||||
|
errMsg := fmt.Sprintf("%s: %v", TerminalErrorMessage, err)
|
||||||
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.InvalidCELExpressionReason, "%s", errMsg)
|
||||||
|
conditions.MarkStalled(obj, meta.InvalidCELExpressionReason, "%s", errMsg)
|
||||||
|
obj.Status.ObservedGeneration = obj.Generation
|
||||||
|
r.event(obj, revision, originRevision, eventv1.EventSeverityError, errMsg, nil)
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retry on transient errors.
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.DependencyNotReadyReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.DependencyNotReadyReason, "%s", err)
|
||||||
msg := fmt.Sprintf("Dependencies do not meet ready condition, retrying in %s", r.requeueDependency.String())
|
msg := fmt.Sprintf("Dependencies do not meet ready condition, retrying in %s", r.DependencyRequeueInterval.String())
|
||||||
log.Info(msg)
|
log.Info(msg)
|
||||||
r.event(obj, revision, originRevision, eventv1.EventSeverityInfo, msg, nil)
|
r.event(obj, revision, originRevision, eventv1.EventSeverityInfo, msg, nil)
|
||||||
return ctrl.Result{RequeueAfter: r.requeueDependency}, nil
|
return ctrl.Result{RequeueAfter: r.DependencyRequeueInterval}, nil
|
||||||
}
|
}
|
||||||
log.Info("All dependencies are ready, proceeding with reconciliation")
|
log.Info("All dependencies are ready, proceeding with reconciliation")
|
||||||
}
|
}
|
||||||
|
@ -307,10 +266,10 @@ func (r *KustomizationReconciler) Reconcile(ctx context.Context, req ctrl.Reques
|
||||||
|
|
||||||
// Requeue at the specified retry interval if the artifact tarball is not found.
|
// Requeue at the specified retry interval if the artifact tarball is not found.
|
||||||
if errors.Is(reconcileErr, fetch.ErrFileNotFound) {
|
if errors.Is(reconcileErr, fetch.ErrFileNotFound) {
|
||||||
msg := fmt.Sprintf("Source is not ready, artifact not found, retrying in %s", r.requeueDependency.String())
|
msg := fmt.Sprintf("Source is not ready, artifact not found, retrying in %s", r.DependencyRequeueInterval.String())
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ArtifactFailedReason, "%s", msg)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ArtifactFailedReason, "%s", msg)
|
||||||
log.Info(msg)
|
log.Info(msg)
|
||||||
return ctrl.Result{RequeueAfter: r.requeueDependency}, nil
|
return ctrl.Result{RequeueAfter: r.DependencyRequeueInterval}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast the reconciliation failure and requeue at the specified retry interval.
|
// Broadcast the reconciliation failure and requeue at the specified retry interval.
|
||||||
|
@ -335,6 +294,7 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
src sourcev1.Source,
|
src sourcev1.Source,
|
||||||
patcher *patch.SerialPatcher,
|
patcher *patch.SerialPatcher,
|
||||||
statusReaders []func(apimeta.RESTMapper) engine.StatusReader) error {
|
statusReaders []func(apimeta.RESTMapper) engine.StatusReader) error {
|
||||||
|
reconcileStart := time.Now()
|
||||||
log := ctrl.LoggerFrom(ctx)
|
log := ctrl.LoggerFrom(ctx)
|
||||||
|
|
||||||
// Update status with the reconciliation progress.
|
// Update status with the reconciliation progress.
|
||||||
|
@ -368,13 +328,14 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
}(tmpDir)
|
}(tmpDir)
|
||||||
|
|
||||||
// Download artifact and extract files to the tmp dir.
|
// Download artifact and extract files to the tmp dir.
|
||||||
if err = fetch.NewArchiveFetcherWithLogger(
|
fetcher := fetch.New(
|
||||||
r.artifactFetchRetries,
|
fetch.WithLogger(ctrl.LoggerFrom(ctx)),
|
||||||
tar.UnlimitedUntarSize,
|
fetch.WithRetries(r.ArtifactFetchRetries),
|
||||||
tar.UnlimitedUntarSize,
|
fetch.WithMaxDownloadSize(tar.UnlimitedUntarSize),
|
||||||
os.Getenv("SOURCE_CONTROLLER_LOCALHOST"),
|
fetch.WithUntar(tar.WithMaxUntarSize(tar.UnlimitedUntarSize)),
|
||||||
ctrl.LoggerFrom(ctx),
|
fetch.WithHostnameOverwrite(os.Getenv("SOURCE_CONTROLLER_LOCALHOST")),
|
||||||
).Fetch(src.GetArtifact().URL, src.GetArtifact().Digest, tmpDir); err != nil {
|
)
|
||||||
|
if err = fetcher.Fetch(src.GetArtifact().URL, src.GetArtifact().Digest, tmpDir); err != nil {
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ArtifactFailedReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ArtifactFailedReason, "%s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -410,8 +371,9 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
}
|
}
|
||||||
if obj.Spec.KubeConfig != nil {
|
if obj.Spec.KubeConfig != nil {
|
||||||
mustImpersonate = true
|
mustImpersonate = true
|
||||||
|
provider := r.getProviderRESTConfigFetcher(obj)
|
||||||
impersonatorOpts = append(impersonatorOpts,
|
impersonatorOpts = append(impersonatorOpts,
|
||||||
runtimeClient.WithKubeConfig(obj.Spec.KubeConfig, r.KubeConfigOpts, obj.GetNamespace()))
|
runtimeClient.WithKubeConfig(obj.Spec.KubeConfig, r.KubeConfigOpts, obj.GetNamespace(), provider))
|
||||||
}
|
}
|
||||||
if r.ClusterReader != nil || len(statusReaders) > 0 {
|
if r.ClusterReader != nil || len(statusReaders) > 0 {
|
||||||
impersonatorOpts = append(impersonatorOpts,
|
impersonatorOpts = append(impersonatorOpts,
|
||||||
|
@ -451,6 +413,13 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the digest of the built resources for history tracking.
|
||||||
|
checksum := digest.FromBytes(resources).String()
|
||||||
|
historyMeta := map[string]string{"revision": revision}
|
||||||
|
if originRevision != "" {
|
||||||
|
historyMeta["originRevision"] = originRevision
|
||||||
|
}
|
||||||
|
|
||||||
// Convert the build result into Kubernetes unstructured objects.
|
// Convert the build result into Kubernetes unstructured objects.
|
||||||
objects, err := ssautil.ReadObjects(bytes.NewReader(resources))
|
objects, err := ssautil.ReadObjects(bytes.NewReader(resources))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -476,6 +445,7 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
// Validate and apply resources in stages.
|
// Validate and apply resources in stages.
|
||||||
drifted, changeSet, err := r.apply(ctx, resourceManager, obj, revision, originRevision, objects)
|
drifted, changeSet, err := r.apply(ctx, resourceManager, obj, revision, originRevision, objects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
obj.Status.History.Upsert(checksum, time.Now(), time.Since(reconcileStart), meta.ReconciliationFailedReason, historyMeta)
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -484,6 +454,7 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
newInventory := inventory.New()
|
newInventory := inventory.New()
|
||||||
err = inventory.AddChangeSet(newInventory, changeSet)
|
err = inventory.AddChangeSet(newInventory, changeSet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
obj.Status.History.Upsert(checksum, time.Now(), time.Since(reconcileStart), meta.ReconciliationFailedReason, historyMeta)
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -494,12 +465,14 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
// Detect stale resources which are subject to garbage collection.
|
// Detect stale resources which are subject to garbage collection.
|
||||||
staleObjects, err := inventory.Diff(oldInventory, newInventory)
|
staleObjects, err := inventory.Diff(oldInventory, newInventory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
obj.Status.History.Upsert(checksum, time.Now(), time.Since(reconcileStart), meta.ReconciliationFailedReason, historyMeta)
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.ReconciliationFailedReason, "%s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run garbage collection for stale resources that do not have pruning disabled.
|
// Run garbage collection for stale resources that do not have pruning disabled.
|
||||||
if _, err := r.prune(ctx, resourceManager, obj, revision, originRevision, staleObjects); err != nil {
|
if _, err := r.prune(ctx, resourceManager, obj, revision, originRevision, staleObjects); err != nil {
|
||||||
|
obj.Status.History.Upsert(checksum, time.Now(), time.Since(reconcileStart), meta.PruneFailedReason, historyMeta)
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.PruneFailedReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.PruneFailedReason, "%s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -515,6 +488,7 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
isNewRevision,
|
isNewRevision,
|
||||||
drifted,
|
drifted,
|
||||||
changeSet.ToObjMetadataSet()); err != nil {
|
changeSet.ToObjMetadataSet()); err != nil {
|
||||||
|
obj.Status.History.Upsert(checksum, time.Now(), time.Since(reconcileStart), meta.HealthCheckFailedReason, historyMeta)
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, meta.HealthCheckFailedReason, "%s", err)
|
conditions.MarkFalse(obj, meta.ReadyCondition, meta.HealthCheckFailedReason, "%s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -528,55 +502,131 @@ func (r *KustomizationReconciler) reconcile(
|
||||||
meta.ReadyCondition,
|
meta.ReadyCondition,
|
||||||
meta.ReconciliationSucceededReason,
|
meta.ReconciliationSucceededReason,
|
||||||
"Applied revision: %s", revision)
|
"Applied revision: %s", revision)
|
||||||
|
obj.Status.History.Upsert(checksum,
|
||||||
|
time.Now(),
|
||||||
|
time.Since(reconcileStart),
|
||||||
|
meta.ReconciliationSucceededReason,
|
||||||
|
historyMeta)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkDependencies checks if the dependencies of the current Kustomization are ready.
|
||||||
|
// To be considered ready, a dependencies must meet the following criteria:
|
||||||
|
// - The dependency exists in the API server.
|
||||||
|
// - The CEL expression (if provided) must evaluate to true.
|
||||||
|
// - The dependency observed generation must match the current generation.
|
||||||
|
// - The dependency Ready condition must be true.
|
||||||
|
// - The dependency last applied revision must match the current source artifact revision.
|
||||||
func (r *KustomizationReconciler) checkDependencies(ctx context.Context,
|
func (r *KustomizationReconciler) checkDependencies(ctx context.Context,
|
||||||
obj *kustomizev1.Kustomization,
|
obj *kustomizev1.Kustomization,
|
||||||
source sourcev1.Source) error {
|
source sourcev1.Source) error {
|
||||||
for _, d := range obj.Spec.DependsOn {
|
|
||||||
if d.Namespace == "" {
|
// Convert the Kustomization object to Unstructured for CEL evaluation.
|
||||||
d.Namespace = obj.GetNamespace()
|
objMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to convert Kustomization to unstructured: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, depRef := range obj.Spec.DependsOn {
|
||||||
|
// Check if the dependency exists by querying
|
||||||
|
// the API server bypassing the cache.
|
||||||
|
if depRef.Namespace == "" {
|
||||||
|
depRef.Namespace = obj.GetNamespace()
|
||||||
}
|
}
|
||||||
dName := types.NamespacedName{
|
depName := types.NamespacedName{
|
||||||
Namespace: d.Namespace,
|
Namespace: depRef.Namespace,
|
||||||
Name: d.Name,
|
Name: depRef.Name,
|
||||||
}
|
}
|
||||||
var k kustomizev1.Kustomization
|
var dep kustomizev1.Kustomization
|
||||||
err := r.APIReader.Get(ctx, dName, &k)
|
err := r.APIReader.Get(ctx, depName, &dep)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("dependency '%s' not found: %w", dName, err)
|
return fmt.Errorf("dependency '%s' not found: %w", depName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(k.Status.Conditions) == 0 || k.Generation != k.Status.ObservedGeneration {
|
// Evaluate the CEL expression (if specified) to determine if the dependency is ready.
|
||||||
return fmt.Errorf("dependency '%s' is not ready", dName)
|
if depRef.ReadyExpr != "" {
|
||||||
|
ready, err := r.evalReadyExpr(ctx, depRef.ReadyExpr, objMap, &dep)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !ready {
|
||||||
|
return fmt.Errorf("dependency '%s' is not ready according to readyExpr eval", depName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apimeta.IsStatusConditionTrue(k.Status.Conditions, meta.ReadyCondition) {
|
// Skip the built-in readiness check if the CEL expression is provided
|
||||||
return fmt.Errorf("dependency '%s' is not ready", dName)
|
// and the AdditiveCELDependencyCheck feature gate is not enabled.
|
||||||
|
if depRef.ReadyExpr != "" && !r.AdditiveCELDependencyCheck {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
srcNamespace := k.Spec.SourceRef.Namespace
|
// Check if the dependency observed generation is up to date
|
||||||
|
// and if the dependency is in a ready state.
|
||||||
|
if len(dep.Status.Conditions) == 0 || dep.Generation != dep.Status.ObservedGeneration {
|
||||||
|
return fmt.Errorf("dependency '%s' is not ready", depName)
|
||||||
|
}
|
||||||
|
if !apimeta.IsStatusConditionTrue(dep.Status.Conditions, meta.ReadyCondition) {
|
||||||
|
return fmt.Errorf("dependency '%s' is not ready", depName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the dependency source matches the current source
|
||||||
|
// and if so, verify that the last applied revision of the dependency
|
||||||
|
// matches the current source artifact revision.
|
||||||
|
srcNamespace := dep.Spec.SourceRef.Namespace
|
||||||
if srcNamespace == "" {
|
if srcNamespace == "" {
|
||||||
srcNamespace = k.GetNamespace()
|
srcNamespace = dep.GetNamespace()
|
||||||
}
|
}
|
||||||
dSrcNamespace := obj.Spec.SourceRef.Namespace
|
depSrcNamespace := obj.Spec.SourceRef.Namespace
|
||||||
if dSrcNamespace == "" {
|
if depSrcNamespace == "" {
|
||||||
dSrcNamespace = obj.GetNamespace()
|
depSrcNamespace = obj.GetNamespace()
|
||||||
}
|
}
|
||||||
|
if dep.Spec.SourceRef.Name == obj.Spec.SourceRef.Name &&
|
||||||
if k.Spec.SourceRef.Name == obj.Spec.SourceRef.Name &&
|
srcNamespace == depSrcNamespace &&
|
||||||
srcNamespace == dSrcNamespace &&
|
dep.Spec.SourceRef.Kind == obj.Spec.SourceRef.Kind &&
|
||||||
k.Spec.SourceRef.Kind == obj.Spec.SourceRef.Kind &&
|
!source.GetArtifact().HasRevision(dep.Status.LastAppliedRevision) {
|
||||||
!source.GetArtifact().HasRevision(k.Status.LastAppliedRevision) {
|
return fmt.Errorf("dependency '%s' revision is not up to date", depName)
|
||||||
return fmt.Errorf("dependency '%s' revision is not up to date", dName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// evalReadyExpr evaluates the CEL expression for the dependency readiness check.
|
||||||
|
func (r *KustomizationReconciler) evalReadyExpr(
|
||||||
|
ctx context.Context,
|
||||||
|
expr string,
|
||||||
|
selfMap map[string]any,
|
||||||
|
dep *kustomizev1.Kustomization,
|
||||||
|
) (bool, error) {
|
||||||
|
const (
|
||||||
|
selfName = "self"
|
||||||
|
depName = "dep"
|
||||||
|
)
|
||||||
|
|
||||||
|
celExpr, err := cel.NewExpression(expr,
|
||||||
|
cel.WithCompile(),
|
||||||
|
cel.WithOutputType(celtypes.BoolType),
|
||||||
|
cel.WithStructVariables(selfName, depName))
|
||||||
|
if err != nil {
|
||||||
|
return false, reconcile.TerminalError(fmt.Errorf("failed to evaluate dependency %s: %w", dep.Name, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
depMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(dep)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to convert %s object to map: %w", depName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
vars := map[string]any{
|
||||||
|
selfName: selfMap,
|
||||||
|
depName: depMap,
|
||||||
|
}
|
||||||
|
|
||||||
|
return celExpr.EvaluateBoolean(ctx, vars)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSource resolves the source reference and returns the source object containing the artifact.
|
||||||
|
// It returns an error if the source is not found or if access is denied.
|
||||||
func (r *KustomizationReconciler) getSource(ctx context.Context,
|
func (r *KustomizationReconciler) getSource(ctx context.Context,
|
||||||
obj *kustomizev1.Kustomization) (sourcev1.Source, error) {
|
obj *kustomizev1.Kustomization) (sourcev1.Source, error) {
|
||||||
var src sourcev1.Source
|
var src sourcev1.Source
|
||||||
|
@ -589,12 +639,20 @@ func (r *KustomizationReconciler) getSource(ctx context.Context,
|
||||||
Name: obj.Spec.SourceRef.Name,
|
Name: obj.Spec.SourceRef.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if cross-namespace references are allowed.
|
||||||
if r.NoCrossNamespaceRefs && sourceNamespace != obj.GetNamespace() {
|
if r.NoCrossNamespaceRefs && sourceNamespace != obj.GetNamespace() {
|
||||||
return src, acl.AccessDeniedError(
|
return src, acl.AccessDeniedError(
|
||||||
fmt.Sprintf("can't access '%s/%s', cross-namespace references have been blocked",
|
fmt.Sprintf("can't access '%s/%s', cross-namespace references have been blocked",
|
||||||
obj.Spec.SourceRef.Kind, namespacedName))
|
obj.Spec.SourceRef.Kind, namespacedName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if ExternalArtifact kind is allowed.
|
||||||
|
if obj.Spec.SourceRef.Kind == sourcev1.ExternalArtifactKind && !r.AllowExternalArtifact {
|
||||||
|
return src, acl.AccessDeniedError(
|
||||||
|
fmt.Sprintf("can't access '%s/%s', %s feature gate is disabled",
|
||||||
|
obj.Spec.SourceRef.Kind, namespacedName, features.ExternalArtifact))
|
||||||
|
}
|
||||||
|
|
||||||
switch obj.Spec.SourceRef.Kind {
|
switch obj.Spec.SourceRef.Kind {
|
||||||
case sourcev1.OCIRepositoryKind:
|
case sourcev1.OCIRepositoryKind:
|
||||||
var repository sourcev1.OCIRepository
|
var repository sourcev1.OCIRepository
|
||||||
|
@ -626,6 +684,16 @@ func (r *KustomizationReconciler) getSource(ctx context.Context,
|
||||||
return src, fmt.Errorf("unable to get source '%s': %w", namespacedName, err)
|
return src, fmt.Errorf("unable to get source '%s': %w", namespacedName, err)
|
||||||
}
|
}
|
||||||
src = &bucket
|
src = &bucket
|
||||||
|
case sourcev1.ExternalArtifactKind:
|
||||||
|
var ea sourcev1.ExternalArtifact
|
||||||
|
err := r.Client.Get(ctx, namespacedName, &ea)
|
||||||
|
if err != nil {
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
return src, err
|
||||||
|
}
|
||||||
|
return src, fmt.Errorf("unable to get source '%s': %w", namespacedName, err)
|
||||||
|
}
|
||||||
|
src = &ea
|
||||||
default:
|
default:
|
||||||
return src, fmt.Errorf("source `%s` kind '%s' not supported",
|
return src, fmt.Errorf("source `%s` kind '%s' not supported",
|
||||||
obj.Spec.SourceRef.Name, obj.Spec.SourceRef.Kind)
|
obj.Spec.SourceRef.Name, obj.Spec.SourceRef.Kind)
|
||||||
|
@ -642,7 +710,18 @@ func (r *KustomizationReconciler) generate(obj unstructured.Unstructured,
|
||||||
func (r *KustomizationReconciler) build(ctx context.Context,
|
func (r *KustomizationReconciler) build(ctx context.Context,
|
||||||
obj *kustomizev1.Kustomization, u unstructured.Unstructured,
|
obj *kustomizev1.Kustomization, u unstructured.Unstructured,
|
||||||
workDir, dirPath string) ([]byte, error) {
|
workDir, dirPath string) ([]byte, error) {
|
||||||
dec, cleanup, err := decryptor.NewTempDecryptor(workDir, r.Client, obj, r.TokenCache)
|
|
||||||
|
// Build decryptor.
|
||||||
|
decryptorOpts := []decryptor.Option{
|
||||||
|
decryptor.WithRoot(workDir),
|
||||||
|
}
|
||||||
|
if r.TokenCache != nil {
|
||||||
|
decryptorOpts = append(decryptorOpts, decryptor.WithTokenCache(*r.TokenCache))
|
||||||
|
}
|
||||||
|
if name, ns := r.SOPSAgeSecret, intruntime.Namespace(); name != "" && ns != "" {
|
||||||
|
decryptorOpts = append(decryptorOpts, decryptor.WithSOPSAgeSecret(name, ns))
|
||||||
|
}
|
||||||
|
dec, cleanup, err := decryptor.New(r.Client, obj, decryptorOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -794,120 +873,44 @@ func (r *KustomizationReconciler) apply(ctx context.Context,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// contains only CRDs and Namespaces
|
|
||||||
var defStage []*unstructured.Unstructured
|
|
||||||
|
|
||||||
// contains only Kubernetes Class types e.g.: RuntimeClass, PriorityClass,
|
|
||||||
// StorageClass, VolumeSnapshotClass, IngressClass, GatewayClass, ClusterClass, etc
|
|
||||||
var classStage []*unstructured.Unstructured
|
|
||||||
|
|
||||||
// contains all objects except for CRDs, Namespaces and Class type objects
|
|
||||||
var resStage []*unstructured.Unstructured
|
|
||||||
|
|
||||||
// contains the objects' metadata after apply
|
|
||||||
resultSet := ssa.NewChangeSet()
|
|
||||||
|
|
||||||
for _, u := range objects {
|
for _, u := range objects {
|
||||||
if decryptor.IsEncryptedSecret(u) {
|
if decryptor.IsEncryptedSecret(u) {
|
||||||
return false, nil,
|
return false, nil,
|
||||||
fmt.Errorf("%s is SOPS encrypted, configuring decryption is required for this secret to be reconciled",
|
fmt.Errorf("%s is SOPS encrypted, configuring decryption is required for this secret to be reconciled",
|
||||||
ssautil.FmtUnstructured(u))
|
ssautil.FmtUnstructured(u))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
|
||||||
case ssautil.IsClusterDefinition(u):
|
|
||||||
defStage = append(defStage, u)
|
|
||||||
case strings.HasSuffix(u.GetKind(), "Class"):
|
|
||||||
classStage = append(classStage, u)
|
|
||||||
default:
|
|
||||||
resStage = append(resStage, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// contains the objects' metadata after apply
|
||||||
|
resultSet := ssa.NewChangeSet()
|
||||||
var changeSetLog strings.Builder
|
var changeSetLog strings.Builder
|
||||||
|
|
||||||
// validate, apply and wait for CRDs and Namespaces to register
|
if len(objects) > 0 {
|
||||||
if len(defStage) > 0 {
|
changeSet, err := manager.ApplyAllStaged(ctx, objects, applyOpts)
|
||||||
changeSet, err := manager.ApplyAll(ctx, defStage, applyOpts)
|
|
||||||
if err != nil {
|
|
||||||
return false, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if changeSet != nil && len(changeSet.Entries) > 0 {
|
if changeSet != nil && len(changeSet.Entries) > 0 {
|
||||||
resultSet.Append(changeSet.Entries)
|
resultSet.Append(changeSet.Entries)
|
||||||
|
|
||||||
if r.GroupChangeLog {
|
// filter out the objects that have not changed
|
||||||
log.Info("server-side apply for cluster definitions completed", "output", changeSet.ToGroupedMap())
|
|
||||||
} else {
|
|
||||||
log.Info("server-side apply for cluster definitions completed", "output", changeSet.ToMap())
|
|
||||||
}
|
|
||||||
for _, change := range changeSet.Entries {
|
for _, change := range changeSet.Entries {
|
||||||
if HasChanged(change.Action) {
|
if HasChanged(change.Action) {
|
||||||
changeSetLog.WriteString(change.String() + "\n")
|
changeSetLog.WriteString(change.String() + "\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := manager.WaitForSet(changeSet.ToObjMetadataSet(), ssa.WaitOptions{
|
|
||||||
Interval: 2 * time.Second,
|
|
||||||
Timeout: obj.GetTimeout(),
|
|
||||||
}); err != nil {
|
|
||||||
return false, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate, apply and wait for Class type objects to register
|
|
||||||
if len(classStage) > 0 {
|
|
||||||
changeSet, err := manager.ApplyAll(ctx, classStage, applyOpts)
|
|
||||||
if err != nil {
|
|
||||||
return false, nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if changeSet != nil && len(changeSet.Entries) > 0 {
|
// include the change log in the error message in case af a partial apply
|
||||||
resultSet.Append(changeSet.Entries)
|
|
||||||
|
|
||||||
if r.GroupChangeLog {
|
|
||||||
log.Info("server-side apply for cluster definitions completed", "output", changeSet.ToGroupedMap())
|
|
||||||
} else {
|
|
||||||
log.Info("server-side apply for cluster class types completed", "output", changeSet.ToMap())
|
|
||||||
}
|
|
||||||
for _, change := range changeSet.Entries {
|
|
||||||
if HasChanged(change.Action) {
|
|
||||||
changeSetLog.WriteString(change.String() + "\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := manager.WaitForSet(changeSet.ToObjMetadataSet(), ssa.WaitOptions{
|
|
||||||
Interval: 2 * time.Second,
|
|
||||||
Timeout: obj.GetTimeout(),
|
|
||||||
}); err != nil {
|
|
||||||
return false, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort by kind, validate and apply all the others objects
|
|
||||||
sort.Sort(ssa.SortableUnstructureds(resStage))
|
|
||||||
if len(resStage) > 0 {
|
|
||||||
changeSet, err := manager.ApplyAll(ctx, resStage, applyOpts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, fmt.Errorf("%w\n%s", err, changeSetLog.String())
|
return false, nil, fmt.Errorf("%w\n%s", err, changeSetLog.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// log all applied objects
|
||||||
if changeSet != nil && len(changeSet.Entries) > 0 {
|
if changeSet != nil && len(changeSet.Entries) > 0 {
|
||||||
resultSet.Append(changeSet.Entries)
|
|
||||||
|
|
||||||
if r.GroupChangeLog {
|
if r.GroupChangeLog {
|
||||||
log.Info("server-side apply for cluster definitions completed", "output", changeSet.ToGroupedMap())
|
log.Info("server-side apply completed", "output", changeSet.ToGroupedMap(), "revision", revision)
|
||||||
} else {
|
} else {
|
||||||
log.Info("server-side apply completed", "output", changeSet.ToMap(), "revision", revision)
|
log.Info("server-side apply completed", "output", changeSet.ToMap(), "revision", revision)
|
||||||
}
|
}
|
||||||
for _, change := range changeSet.Entries {
|
|
||||||
if HasChanged(change.Action) {
|
|
||||||
changeSetLog.WriteString(change.String() + "\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1076,8 +1079,9 @@ func (r *KustomizationReconciler) finalize(ctx context.Context,
|
||||||
}
|
}
|
||||||
if obj.Spec.KubeConfig != nil {
|
if obj.Spec.KubeConfig != nil {
|
||||||
mustImpersonate = true
|
mustImpersonate = true
|
||||||
|
provider := r.getProviderRESTConfigFetcher(obj)
|
||||||
impersonatorOpts = append(impersonatorOpts,
|
impersonatorOpts = append(impersonatorOpts,
|
||||||
runtimeClient.WithKubeConfig(obj.Spec.KubeConfig, r.KubeConfigOpts, obj.GetNamespace()))
|
runtimeClient.WithKubeConfig(obj.Spec.KubeConfig, r.KubeConfigOpts, obj.GetNamespace(), provider))
|
||||||
}
|
}
|
||||||
if r.ClusterReader != nil {
|
if r.ClusterReader != nil {
|
||||||
impersonatorOpts = append(impersonatorOpts, runtimeClient.WithPolling(r.ClusterReader))
|
impersonatorOpts = append(impersonatorOpts, runtimeClient.WithPolling(r.ClusterReader))
|
||||||
|
@ -1222,7 +1226,7 @@ func (r *KustomizationReconciler) patch(ctx context.Context,
|
||||||
patchOpts = append(patchOpts,
|
patchOpts = append(patchOpts,
|
||||||
patch.WithOwnedConditions{Conditions: ownedConditions},
|
patch.WithOwnedConditions{Conditions: ownedConditions},
|
||||||
patch.WithForceOverwriteConditions{},
|
patch.WithForceOverwriteConditions{},
|
||||||
patch.WithFieldOwner(r.statusManager),
|
patch.WithFieldOwner(r.StatusManager),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Patch the object status, conditions and finalizers.
|
// Patch the object status, conditions and finalizers.
|
||||||
|
@ -1262,6 +1266,27 @@ func (r *KustomizationReconciler) getClientAndPoller(
|
||||||
return r.Client, poller
|
return r.Client, poller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getProviderRESTConfigFetcher returns a ProviderRESTConfigFetcher for the
|
||||||
|
// Kustomization object, which is used to fetch the kubeconfig for a ConfigMap
|
||||||
|
// reference in the Kustomization spec.
|
||||||
|
func (r *KustomizationReconciler) getProviderRESTConfigFetcher(obj *kustomizev1.Kustomization) runtimeClient.ProviderRESTConfigFetcher {
|
||||||
|
var provider runtimeClient.ProviderRESTConfigFetcher
|
||||||
|
if kc := obj.Spec.KubeConfig; kc != nil && kc.SecretRef == nil && kc.ConfigMapRef != nil {
|
||||||
|
var opts []auth.Option
|
||||||
|
if r.TokenCache != nil {
|
||||||
|
involvedObject := cache.InvolvedObject{
|
||||||
|
Kind: kustomizev1.KustomizationKind,
|
||||||
|
Name: obj.GetName(),
|
||||||
|
Namespace: obj.GetNamespace(),
|
||||||
|
Operation: intcache.OperationFetchKubeConfig,
|
||||||
|
}
|
||||||
|
opts = append(opts, auth.WithCache(*r.TokenCache, involvedObject))
|
||||||
|
}
|
||||||
|
provider = runtimeClient.ProviderRESTConfigFetcher(authutils.GetRESTConfigFetcher(opts...))
|
||||||
|
}
|
||||||
|
return provider
|
||||||
|
}
|
||||||
|
|
||||||
// getOriginRevision returns the origin revision of the source artifact,
|
// getOriginRevision returns the origin revision of the source artifact,
|
||||||
// or the empty string if it's not present, or if the artifact itself
|
// or the empty string if it's not present, or if the artifact itself
|
||||||
// is not present.
|
// is not present.
|
||||||
|
|
|
@ -76,7 +76,7 @@ func TestKustomizationReconciler_StagedApply(t *testing.T) {
|
||||||
Kind: sourcev1.GitRepositoryKind,
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
},
|
},
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -114,7 +114,7 @@ func TestKustomizationReconciler_Decryptor(t *testing.T) {
|
||||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -194,4 +194,172 @@ func TestKustomizationReconciler_Decryptor(t *testing.T) {
|
||||||
g.Expect(events[0].Message).Should(ContainSubstring("Reconciliation finished"))
|
g.Expect(events[0].Message).Should(ContainSubstring("Reconciliation finished"))
|
||||||
g.Expect(events[0].Message).ShouldNot(ContainSubstring("configured"))
|
g.Expect(events[0].Message).ShouldNot(ContainSubstring("configured"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("global SOPS age secret as fallback", func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
namespace := "global-sops-" + randStringRunes(5)
|
||||||
|
t.Setenv("RUNTIME_NAMESPACE", namespace)
|
||||||
|
|
||||||
|
err := createNamespace(namespace)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Create the global SOPS age secret with the private key
|
||||||
|
ageKey, err := os.ReadFile("testdata/sops/keys/age-global.txt")
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
globalSOPSSecret := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: sopsAgeSecret,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
StringData: map[string]string{
|
||||||
|
"identity.agekey": string(ageKey),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), globalSOPSSecret)).To(Succeed())
|
||||||
|
|
||||||
|
artifactName := "global-sops-" + randStringRunes(5)
|
||||||
|
artifactChecksum, err := testServer.ArtifactFromDir("testdata/sops/global", artifactName)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
repositoryName := types.NamespacedName{
|
||||||
|
Name: fmt.Sprintf("global-sops-%s", randStringRunes(5)),
|
||||||
|
Namespace: namespace,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = applyGitRepository(repositoryName, artifactName, "main/"+artifactChecksum)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Create Kustomization WITHOUT spec.decryption.secretRef
|
||||||
|
kustomizationKey := types.NamespacedName{
|
||||||
|
Name: fmt.Sprintf("global-sops-%s", randStringRunes(5)),
|
||||||
|
Namespace: namespace,
|
||||||
|
}
|
||||||
|
kustomization := &kustomizev1.Kustomization{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kustomizationKey.Name,
|
||||||
|
Namespace: kustomizationKey.Namespace,
|
||||||
|
},
|
||||||
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
|
Path: "./",
|
||||||
|
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||||
|
Name: repositoryName.Name,
|
||||||
|
Namespace: repositoryName.Namespace,
|
||||||
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
|
},
|
||||||
|
TargetNamespace: namespace,
|
||||||
|
Decryption: &kustomizev1.Decryption{
|
||||||
|
Provider: "sops",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
|
||||||
|
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
var obj kustomizev1.Kustomization
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), &obj)
|
||||||
|
return obj.Status.LastAppliedRevision == "main/"+artifactChecksum
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
// Verify the SOPS encrypted secret was decrypted using the global secret
|
||||||
|
var secret corev1.Secret
|
||||||
|
g.Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: "global-age-secret", Namespace: namespace}, &secret)).To(Succeed())
|
||||||
|
g.Expect(string(secret.Data["key"])).To(Equal("global-value"))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("spec.decryption.secretRef takes precedence over global secret", func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
namespace := "precedence-" + randStringRunes(5)
|
||||||
|
t.Setenv("RUNTIME_NAMESPACE", namespace)
|
||||||
|
|
||||||
|
err := createNamespace(namespace)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Create global SOPS secret
|
||||||
|
ageGlobalKey, err := os.ReadFile("testdata/sops/keys/age-global.txt")
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
globalSOPSSecret := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: sopsAgeSecret,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
StringData: map[string]string{
|
||||||
|
"identity.agekey": string(ageGlobalKey),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), globalSOPSSecret)).To(Succeed())
|
||||||
|
|
||||||
|
localSOPSSecretKey := types.NamespacedName{
|
||||||
|
Name: "local-sops-" + randStringRunes(5),
|
||||||
|
Namespace: namespace,
|
||||||
|
}
|
||||||
|
localSOPSSecret := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: localSOPSSecretKey.Name,
|
||||||
|
Namespace: localSOPSSecretKey.Namespace,
|
||||||
|
},
|
||||||
|
StringData: map[string]string{
|
||||||
|
"pgp.asc": string(pgpKey),
|
||||||
|
"age.agekey": string(ageKey),
|
||||||
|
"sops.vault-token": "secret",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), localSOPSSecret)).To(Succeed())
|
||||||
|
|
||||||
|
artifactName := "precedence-" + randStringRunes(5)
|
||||||
|
artifactChecksum, err := testServer.ArtifactFromDir("testdata/sops/algorithms", artifactName)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
repositoryName := types.NamespacedName{
|
||||||
|
Name: fmt.Sprintf("precedence-%s", randStringRunes(5)),
|
||||||
|
Namespace: namespace,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = applyGitRepository(repositoryName, artifactName, "main/"+artifactChecksum)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Create Kustomization WITH spec.decryption.secretRef
|
||||||
|
kustomizationKey := types.NamespacedName{
|
||||||
|
Name: fmt.Sprintf("precedence-%s", randStringRunes(5)),
|
||||||
|
Namespace: namespace,
|
||||||
|
}
|
||||||
|
kustomization := &kustomizev1.Kustomization{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kustomizationKey.Name,
|
||||||
|
Namespace: kustomizationKey.Namespace,
|
||||||
|
},
|
||||||
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
|
Path: "./",
|
||||||
|
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||||
|
Name: repositoryName.Name,
|
||||||
|
Namespace: repositoryName.Namespace,
|
||||||
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
|
},
|
||||||
|
Decryption: &kustomizev1.Decryption{
|
||||||
|
Provider: "sops",
|
||||||
|
SecretRef: &meta.LocalObjectReference{
|
||||||
|
Name: localSOPSSecretKey.Name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TargetNamespace: namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
|
||||||
|
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
var obj kustomizev1.Kustomization
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), &obj)
|
||||||
|
return obj.Status.LastAppliedRevision == "main/"+artifactChecksum
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
// Verify the secret was decrypted using the local secret (not the global one)
|
||||||
|
var secret corev1.Secret
|
||||||
|
g.Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: "algo-age", Namespace: namespace}, &secret)).To(Succeed())
|
||||||
|
g.Expect(string(secret.Data["key"])).To(Equal("value"))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,14 +19,16 @@ package controller
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
"github.com/fluxcd/pkg/runtime/conditions"
|
||||||
"github.com/fluxcd/pkg/testserver"
|
"github.com/fluxcd/pkg/testserver"
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
@ -117,10 +119,10 @@ spec:
|
||||||
Namespace: kustomizationKey.Namespace,
|
Namespace: kustomizationKey.Namespace,
|
||||||
},
|
},
|
||||||
Spec: kustomizev1.KustomizationSpec{
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: time.Hour},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -140,15 +142,14 @@ spec:
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
return apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition) != nil
|
return conditions.Has(resultK, meta.ReadyCondition)
|
||||||
}, timeout, time.Second).Should(BeTrue())
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
t.Run("fails due to source not found", func(t *testing.T) {
|
t.Run("fails due to source not found", func(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
ready := apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
|
return conditions.HasAnyReason(resultK, meta.ReadyCondition, meta.ArtifactFailedReason)
|
||||||
return ready.Reason == meta.ArtifactFailedReason
|
|
||||||
}, timeout, time.Second).Should(BeTrue())
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -159,8 +160,7 @@ spec:
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
ready := apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
|
return conditions.IsReady(resultK)
|
||||||
return ready.Reason == meta.ReconciliationSucceededReason
|
|
||||||
}, timeout, time.Second).Should(BeTrue())
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ spec:
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
g.Eventually(func() error {
|
g.Eventually(func() error {
|
||||||
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
resultK.Spec.DependsOn = []meta.NamespacedObjectReference{
|
resultK.Spec.DependsOn = []kustomizev1.DependencyReference{
|
||||||
{
|
{
|
||||||
Namespace: id,
|
Namespace: id,
|
||||||
Name: "root",
|
Name: "root",
|
||||||
|
@ -179,8 +179,203 @@ spec:
|
||||||
|
|
||||||
g.Eventually(func() bool {
|
g.Eventually(func() bool {
|
||||||
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
ready := apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
|
return conditions.HasAnyReason(resultK, meta.ReadyCondition, meta.DependencyNotReadyReason)
|
||||||
return ready.Reason == meta.DependencyNotReadyReason
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKustomizationReconciler_DependsOn_CEL(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
id := "dep-cel" + randStringRunes(5)
|
||||||
|
depID := "test-dep-" + randStringRunes(5)
|
||||||
|
revision := "v1.0.0"
|
||||||
|
|
||||||
|
err := createNamespace(id)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
|
||||||
|
|
||||||
|
err = createKubeConfigSecret(id)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
|
||||||
|
|
||||||
|
manifests := func(name string, data string) []testserver.File {
|
||||||
|
return []testserver.File{
|
||||||
|
{
|
||||||
|
Name: "config.yaml",
|
||||||
|
Body: fmt.Sprintf(`---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: %[1]s
|
||||||
|
data:
|
||||||
|
key: "%[2]s"
|
||||||
|
`, name, data),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact, err := testServer.ArtifactFromFiles(manifests(id, id))
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
repositoryName := types.NamespacedName{
|
||||||
|
Name: fmt.Sprintf("dep-%s", randStringRunes(5)),
|
||||||
|
Namespace: id,
|
||||||
|
}
|
||||||
|
err = applyGitRepository(repositoryName, artifact, revision)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
kustomizationKey := types.NamespacedName{
|
||||||
|
Name: fmt.Sprintf("dep-%s", randStringRunes(5)),
|
||||||
|
Namespace: id,
|
||||||
|
}
|
||||||
|
kustomization := &kustomizev1.Kustomization{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kustomizationKey.Name,
|
||||||
|
Namespace: kustomizationKey.Namespace,
|
||||||
|
},
|
||||||
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
|
Interval: metav1.Duration{Duration: time.Hour},
|
||||||
|
Path: "./",
|
||||||
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
|
SecretRef: &meta.SecretKeyReference{
|
||||||
|
Name: "kubeconfig",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||||
|
Name: repositoryName.Name,
|
||||||
|
Namespace: repositoryName.Namespace,
|
||||||
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
|
},
|
||||||
|
TargetNamespace: id,
|
||||||
|
Prune: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
|
||||||
|
|
||||||
|
resultK := &kustomizev1.Kustomization{}
|
||||||
|
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
return conditions.Has(resultK, meta.ReadyCondition)
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
t.Run("succeeds with readyExpr dependency check", func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
// Create a dependency Kustomization with matching annotations
|
||||||
|
dependency := &kustomizev1.Kustomization{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: depID,
|
||||||
|
Namespace: id,
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"app/version": "v1.2.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
|
Suspend: true, // Suspended dependency should work with readyExpr and AdditiveCELDependencyCheck disabled
|
||||||
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
|
Path: "./",
|
||||||
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
|
SecretRef: &meta.SecretKeyReference{
|
||||||
|
Name: "kubeconfig",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||||
|
Name: repositoryName.Name,
|
||||||
|
Namespace: repositoryName.Namespace,
|
||||||
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
|
},
|
||||||
|
Prune: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), dependency)).To(Succeed())
|
||||||
|
|
||||||
|
// Update the main Kustomization with matching annotations and readyExpr
|
||||||
|
g.Eventually(func() error {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
resultK.ObjectMeta.Annotations = map[string]string{
|
||||||
|
"app/version": "v1.2.3",
|
||||||
|
}
|
||||||
|
resultK.Spec.DependsOn = []kustomizev1.DependencyReference{
|
||||||
|
{
|
||||||
|
Name: dependency.Name,
|
||||||
|
ReadyExpr: `self.metadata.annotations['app/version'] == dep.metadata.annotations['app/version']`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return k8sClient.Update(context.Background(), resultK)
|
||||||
|
}, timeout, time.Second).Should(BeNil())
|
||||||
|
|
||||||
|
// Should succeed because CEL expression evaluates to true
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
return conditions.IsReady(resultK)
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("fails with readyExpr when condition not met", func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
// Update the main kustomization with mismatched annotations
|
||||||
|
g.Eventually(func() error {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
resultK.ObjectMeta.Annotations = map[string]string{
|
||||||
|
"app/version": "v1.2.4",
|
||||||
|
}
|
||||||
|
resultK.Spec.DependsOn = []kustomizev1.DependencyReference{
|
||||||
|
{
|
||||||
|
Namespace: id,
|
||||||
|
Name: depID,
|
||||||
|
ReadyExpr: `self.metadata.annotations['app/version'] == dep.metadata.annotations['app/version']`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return k8sClient.Update(context.Background(), resultK)
|
||||||
|
}, timeout, time.Second).Should(BeNil())
|
||||||
|
|
||||||
|
// Should fail because CEL expression evaluates to false
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
ready := conditions.Get(resultK, meta.ReadyCondition)
|
||||||
|
return ready.Reason == meta.DependencyNotReadyReason &&
|
||||||
|
strings.Contains(ready.Message, "not ready according to readyExpr")
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
g.Expect(conditions.IsStalled(resultK)).Should(BeFalse())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("fails terminally with invalid readyExpr", func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
// Update the main kustomization with invalid CEL expression
|
||||||
|
g.Eventually(func() error {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
resultK.Spec.DependsOn = []kustomizev1.DependencyReference{
|
||||||
|
{
|
||||||
|
Name: depID,
|
||||||
|
ReadyExpr: `self.generation == deps.generation`, // Invalid vars
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return k8sClient.Update(context.Background(), resultK)
|
||||||
|
}, timeout, time.Second).Should(BeNil())
|
||||||
|
|
||||||
|
// Should be marked as stalled because CEL expression is invalid
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
return conditions.IsStalled(resultK)
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
g.Expect(conditions.IsReady(resultK)).Should(BeFalse())
|
||||||
|
g.Expect(conditions.GetReason(resultK, meta.ReadyCondition)).Should(BeIdenticalTo(meta.InvalidCELExpressionReason))
|
||||||
|
g.Expect(conditions.GetMessage(resultK, meta.ReadyCondition)).Should(ContainSubstring("failed to parse"))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("GC works with failing dependency", func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
g.Expect(k8sClient.Delete(context.Background(), kustomization)).To(Succeed())
|
||||||
|
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
err = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
return errors.IsNotFound(err)
|
||||||
}, timeout, time.Second).Should(BeTrue())
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
apiacl "github.com/fluxcd/pkg/apis/acl"
|
||||||
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
"github.com/fluxcd/pkg/testserver"
|
||||||
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestKustomizationReconciler_ExternalArtifact(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
id := "ea-" + randStringRunes(5)
|
||||||
|
revision := "v1.0.0"
|
||||||
|
reconciler.AllowExternalArtifact = true
|
||||||
|
|
||||||
|
err := createNamespace(id)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
|
||||||
|
|
||||||
|
err = createKubeConfigSecret(id)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
|
||||||
|
|
||||||
|
manifests := func(name string, data string) []testserver.File {
|
||||||
|
return []testserver.File{
|
||||||
|
{
|
||||||
|
Name: "secret.yaml",
|
||||||
|
Body: fmt.Sprintf(`---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: %[1]s
|
||||||
|
stringData:
|
||||||
|
key: "%[2]s"
|
||||||
|
`, name, data),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact, err := testServer.ArtifactFromFiles(manifests(id, randStringRunes(5)))
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "failed to create artifact from files")
|
||||||
|
|
||||||
|
eaName := types.NamespacedName{
|
||||||
|
Name: randStringRunes(5),
|
||||||
|
Namespace: id,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = applyExternalArtifact(eaName, artifact, revision)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
kustomizationKey := types.NamespacedName{
|
||||||
|
Name: fmt.Sprintf("ea-%s", randStringRunes(5)),
|
||||||
|
Namespace: id,
|
||||||
|
}
|
||||||
|
kustomization := &kustomizev1.Kustomization{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kustomizationKey.Name,
|
||||||
|
Namespace: kustomizationKey.Namespace,
|
||||||
|
},
|
||||||
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
|
Interval: metav1.Duration{Duration: time.Hour},
|
||||||
|
Path: "./",
|
||||||
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
|
SecretRef: &meta.SecretKeyReference{
|
||||||
|
Name: "kubeconfig",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||||
|
Name: eaName.Name,
|
||||||
|
Namespace: eaName.Namespace,
|
||||||
|
Kind: sourcev1.ExternalArtifactKind,
|
||||||
|
},
|
||||||
|
TargetNamespace: id,
|
||||||
|
Wait: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
|
||||||
|
|
||||||
|
resultK := &kustomizev1.Kustomization{}
|
||||||
|
readyCondition := &metav1.Condition{}
|
||||||
|
|
||||||
|
t.Run("reconciles from external artifact source", func(t *testing.T) {
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
readyCondition = apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
|
||||||
|
return resultK.Status.LastAppliedRevision == revision
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
g.Expect(readyCondition.Reason).To(Equal(meta.ReconciliationSucceededReason))
|
||||||
|
g.Expect(resultK.Status.LastAppliedRevision).To(Equal(revision))
|
||||||
|
|
||||||
|
events := getEvents(resultK.GetName(), map[string]string{"kustomize.toolkit.fluxcd.io/revision": revision})
|
||||||
|
g.Expect(len(events) > 2).To(BeTrue())
|
||||||
|
g.Expect(events[0].Reason).To(BeIdenticalTo(meta.ProgressingReason))
|
||||||
|
g.Expect(events[0].Message).To(ContainSubstring("created"))
|
||||||
|
g.Expect(events[1].Reason).To(BeIdenticalTo(meta.ProgressingReason))
|
||||||
|
g.Expect(events[1].Message).To(ContainSubstring("check passed"))
|
||||||
|
g.Expect(events[2].Reason).To(BeIdenticalTo(meta.ReconciliationSucceededReason))
|
||||||
|
g.Expect(events[2].Message).To(ContainSubstring("finished"))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("watches for external artifact revision change", func(t *testing.T) {
|
||||||
|
newRev := "v2.0.0"
|
||||||
|
|
||||||
|
err = applyExternalArtifact(eaName, artifact, newRev)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
return resultK.Status.LastAppliedRevision == newRev
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
g.Expect(resultK.Status.History).To(HaveLen(1))
|
||||||
|
g.Expect(resultK.Status.History[0].TotalReconciliations).To(BeEquivalentTo(2))
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciledStatus).To(Equal(meta.ReconciliationSucceededReason))
|
||||||
|
g.Expect(resultK.Status.History[0].Metadata).To(ContainElements(newRev))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("fails when external artifact feature gate is disable", func(t *testing.T) {
|
||||||
|
newRev := "v3.0.0"
|
||||||
|
reconciler.AllowExternalArtifact = false
|
||||||
|
|
||||||
|
err = applyExternalArtifact(eaName, artifact, newRev)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
|
||||||
|
readyCondition = apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
|
||||||
|
return apimeta.IsStatusConditionFalse(resultK.Status.Conditions, meta.ReadyCondition)
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
g.Expect(readyCondition.Reason).To(Equal(apiacl.AccessDeniedReason))
|
||||||
|
g.Expect(apimeta.IsStatusConditionTrue(resultK.Status.Conditions, meta.StalledCondition)).Should(BeTrue())
|
||||||
|
|
||||||
|
events := getEvents(resultK.GetName(), nil)
|
||||||
|
g.Expect(events[len(events)-1].Reason).To(BeIdenticalTo(apiacl.AccessDeniedReason))
|
||||||
|
g.Expect(events[len(events)-1].Message).To(ContainSubstring("feature gate is disabled"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyExternalArtifact(objKey client.ObjectKey, artifactName string, revision string) error {
|
||||||
|
ea := &sourcev1.ExternalArtifact{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: sourcev1.ExternalArtifactKind,
|
||||||
|
APIVersion: sourcev1.GroupVersion.String(),
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: objKey.Name,
|
||||||
|
Namespace: objKey.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
b, _ := os.ReadFile(filepath.Join(testServer.Root(), artifactName))
|
||||||
|
dig := digest.SHA256.FromBytes(b)
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s/%s", testServer.URL(), artifactName)
|
||||||
|
|
||||||
|
status := sourcev1.ExternalArtifactStatus{
|
||||||
|
Conditions: []metav1.Condition{
|
||||||
|
{
|
||||||
|
Type: meta.ReadyCondition,
|
||||||
|
Status: metav1.ConditionTrue,
|
||||||
|
LastTransitionTime: metav1.Now(),
|
||||||
|
Reason: meta.SucceededReason,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Artifact: &meta.Artifact{
|
||||||
|
Path: url,
|
||||||
|
URL: url,
|
||||||
|
Revision: revision,
|
||||||
|
Digest: dig.String(),
|
||||||
|
LastUpdateTime: metav1.Now(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
patchOpts := []client.PatchOption{
|
||||||
|
client.ForceOwnership,
|
||||||
|
client.FieldOwner("kustomize-controller"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := k8sClient.Patch(context.Background(), ea, client.Apply, patchOpts...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ea.ManagedFields = nil
|
||||||
|
ea.Status = status
|
||||||
|
|
||||||
|
statusOpts := &client.SubResourcePatchOptions{
|
||||||
|
PatchOptions: client.PatchOptions{
|
||||||
|
FieldManager: "source-controller",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := k8sClient.Status().Patch(context.Background(), ea, client.Apply, statusOpts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -86,7 +86,7 @@ stringData:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -87,7 +87,7 @@ stringData:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -232,7 +232,7 @@ func Fuzz_Controllers(f *testing.F) {
|
||||||
Spec: kustomizev1.KustomizationSpec{
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -93,7 +93,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: time.Minute},
|
Interval: metav1.Duration{Duration: time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -261,7 +261,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: time.Minute},
|
Interval: metav1.Duration{Duration: time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: secretName,
|
Name: secretName,
|
||||||
Key: secretKey,
|
Key: secretKey,
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,14 +20,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/runtime/conditions"
|
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
"github.com/fluxcd/pkg/runtime/conditions"
|
||||||
"github.com/fluxcd/pkg/runtime/dependency"
|
"github.com/fluxcd/pkg/runtime/dependency"
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
|
||||||
|
|
||||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
)
|
)
|
||||||
|
@ -36,7 +36,7 @@ func (r *KustomizationReconciler) requestsForRevisionChangeOf(indexKey string) h
|
||||||
return func(ctx context.Context, obj client.Object) []reconcile.Request {
|
return func(ctx context.Context, obj client.Object) []reconcile.Request {
|
||||||
log := ctrl.LoggerFrom(ctx)
|
log := ctrl.LoggerFrom(ctx)
|
||||||
repo, ok := obj.(interface {
|
repo, ok := obj.(interface {
|
||||||
GetArtifact() *sourcev1.Artifact
|
GetArtifact() *meta.Artifact
|
||||||
})
|
})
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Error(fmt.Errorf("expected an object conformed with GetArtifact() method, but got a %T", obj),
|
log.Error(fmt.Errorf("expected an object conformed with GetArtifact() method, but got a %T", obj),
|
||||||
|
@ -64,16 +64,11 @@ func (r *KustomizationReconciler) requestsForRevisionChangeOf(indexKey string) h
|
||||||
}
|
}
|
||||||
dd = append(dd, d.DeepCopy())
|
dd = append(dd, d.DeepCopy())
|
||||||
}
|
}
|
||||||
sorted, err := dependency.Sort(dd)
|
reqs, err := sortAndEnqueue(dd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err, "failed to sort dependencies for revision change")
|
log.Error(err, "failed to sort dependencies for revision change")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
reqs := make([]reconcile.Request, len(sorted))
|
|
||||||
for i := range sorted {
|
|
||||||
reqs[i].NamespacedName.Name = sorted[i].Name
|
|
||||||
reqs[i].NamespacedName.Namespace = sorted[i].Namespace
|
|
||||||
}
|
|
||||||
return reqs
|
return reqs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,3 +91,54 @@ func (r *KustomizationReconciler) indexBy(kind string) func(o client.Object) []s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// requestsForConfigDependency enqueues requests for watched ConfigMaps or Secrets
|
||||||
|
// according to the specified index.
|
||||||
|
func (r *KustomizationReconciler) requestsForConfigDependency(
|
||||||
|
index string) func(ctx context.Context, o client.Object) []reconcile.Request {
|
||||||
|
|
||||||
|
return func(ctx context.Context, o client.Object) []reconcile.Request {
|
||||||
|
log := ctrl.LoggerFrom(ctx).WithValues("index", index, "objectRef", map[string]string{
|
||||||
|
"name": o.GetName(),
|
||||||
|
"namespace": o.GetNamespace(),
|
||||||
|
})
|
||||||
|
|
||||||
|
// List Kustomizations that have a dependency on the ConfigMap or Secret.
|
||||||
|
var list kustomizev1.KustomizationList
|
||||||
|
if err := r.List(ctx, &list, client.MatchingFields{
|
||||||
|
index: client.ObjectKeyFromObject(o).String(),
|
||||||
|
}); err != nil {
|
||||||
|
log.Error(err, "failed to list Kustomizations for config dependency change")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the Kustomizations by their dependencies to ensure
|
||||||
|
// that dependent Kustomizations are reconciled after their dependencies.
|
||||||
|
dd := make([]dependency.Dependent, 0, len(list.Items))
|
||||||
|
for i := range list.Items {
|
||||||
|
dd = append(dd, &list.Items[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enqueue requests for each Kustomization in the list.
|
||||||
|
reqs, err := sortAndEnqueue(dd)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err, "failed to sort dependencies for config dependency change")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return reqs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sortAndEnqueue sorts the dependencies and returns a slice of reconcile.Requests.
|
||||||
|
func sortAndEnqueue(dd []dependency.Dependent) ([]reconcile.Request, error) {
|
||||||
|
sorted, err := dependency.Sort(dd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reqs := make([]reconcile.Request, len(sorted))
|
||||||
|
for i := range sorted {
|
||||||
|
reqs[i].NamespacedName.Name = sorted[i].Name
|
||||||
|
reqs[i].NamespacedName.Namespace = sorted[i].Namespace
|
||||||
|
}
|
||||||
|
return reqs, nil
|
||||||
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ stringData:
|
||||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/client-go/util/workqueue"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
|
"github.com/fluxcd/pkg/runtime/predicates"
|
||||||
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
|
|
||||||
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KustomizationReconcilerOptions contains options for the KustomizationReconciler.
|
||||||
|
type KustomizationReconcilerOptions struct {
|
||||||
|
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
|
||||||
|
WatchConfigsPredicate predicate.Predicate
|
||||||
|
WatchExternalArtifacts bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupWithManager sets up the controller with the Manager.
|
||||||
|
// It indexes the Kustomizations by the source references, and sets up watches for
|
||||||
|
// changes in those sources, as well as for ConfigMaps and Secrets that the Kustomizations depend on.
|
||||||
|
func (r *KustomizationReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, opts KustomizationReconcilerOptions) error {
|
||||||
|
const (
|
||||||
|
indexExternalArtifact = ".metadata.externalArtifact"
|
||||||
|
indexOCIRepository = ".metadata.ociRepository"
|
||||||
|
indexGitRepository = ".metadata.gitRepository"
|
||||||
|
indexBucket = ".metadata.bucket"
|
||||||
|
indexConfigMap = ".metadata.configMap"
|
||||||
|
indexSecret = ".metadata.secret"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Index the Kustomizations by the OCIRepository references they (may) point at.
|
||||||
|
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, indexOCIRepository,
|
||||||
|
r.indexBy(sourcev1.OCIRepositoryKind)); err != nil {
|
||||||
|
return fmt.Errorf("failed creating index %s: %w", indexOCIRepository, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index the Kustomizations by the GitRepository references they (may) point at.
|
||||||
|
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, indexGitRepository,
|
||||||
|
r.indexBy(sourcev1.GitRepositoryKind)); err != nil {
|
||||||
|
return fmt.Errorf("failed creating index %s: %w", indexGitRepository, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index the Kustomizations by the Bucket references they (may) point at.
|
||||||
|
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, indexBucket,
|
||||||
|
r.indexBy(sourcev1.BucketKind)); err != nil {
|
||||||
|
return fmt.Errorf("failed creating index %s: %w", indexBucket, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index the Kustomizations by the ExternalArtifact references they (may) point at (if enabled).
|
||||||
|
if opts.WatchExternalArtifacts {
|
||||||
|
if err := mgr.GetCache().IndexField(ctx, &kustomizev1.Kustomization{}, indexExternalArtifact,
|
||||||
|
r.indexBy(sourcev1.ExternalArtifactKind)); err != nil {
|
||||||
|
return fmt.Errorf("failed creating index %s: %w", indexExternalArtifact, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index the Kustomization by the ConfigMap references they point to.
|
||||||
|
if err := mgr.GetFieldIndexer().IndexField(ctx, &kustomizev1.Kustomization{}, indexConfigMap,
|
||||||
|
func(o client.Object) []string {
|
||||||
|
obj := o.(*kustomizev1.Kustomization)
|
||||||
|
namespace := obj.GetNamespace()
|
||||||
|
var keys []string
|
||||||
|
if kc := obj.Spec.KubeConfig; kc != nil && kc.ConfigMapRef != nil {
|
||||||
|
keys = append(keys, fmt.Sprintf("%s/%s", namespace, kc.ConfigMapRef.Name))
|
||||||
|
}
|
||||||
|
if pb := obj.Spec.PostBuild; pb != nil {
|
||||||
|
for _, ref := range pb.SubstituteFrom {
|
||||||
|
if ref.Kind == "ConfigMap" {
|
||||||
|
keys = append(keys, fmt.Sprintf("%s/%s", namespace, ref.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("failed creating index %s: %w", indexConfigMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index the Kustomization by the Secret references they point to.
|
||||||
|
if err := mgr.GetFieldIndexer().IndexField(ctx, &kustomizev1.Kustomization{}, indexSecret,
|
||||||
|
func(o client.Object) []string {
|
||||||
|
obj := o.(*kustomizev1.Kustomization)
|
||||||
|
namespace := obj.GetNamespace()
|
||||||
|
var keys []string
|
||||||
|
if dec := obj.Spec.Decryption; dec != nil && dec.SecretRef != nil {
|
||||||
|
keys = append(keys, fmt.Sprintf("%s/%s", namespace, dec.SecretRef.Name))
|
||||||
|
}
|
||||||
|
if kc := obj.Spec.KubeConfig; kc != nil && kc.SecretRef != nil {
|
||||||
|
keys = append(keys, fmt.Sprintf("%s/%s", namespace, kc.SecretRef.Name))
|
||||||
|
}
|
||||||
|
if pb := obj.Spec.PostBuild; pb != nil {
|
||||||
|
for _, ref := range pb.SubstituteFrom {
|
||||||
|
if ref.Kind == "Secret" {
|
||||||
|
keys = append(keys, fmt.Sprintf("%s/%s", namespace, ref.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("failed creating index %s: %w", indexSecret, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrlBuilder := ctrl.NewControllerManagedBy(mgr).
|
||||||
|
For(&kustomizev1.Kustomization{}, builder.WithPredicates(
|
||||||
|
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
|
||||||
|
)).
|
||||||
|
Watches(
|
||||||
|
&sourcev1.OCIRepository{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(indexOCIRepository)),
|
||||||
|
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
||||||
|
).
|
||||||
|
Watches(
|
||||||
|
&sourcev1.GitRepository{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(indexGitRepository)),
|
||||||
|
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
||||||
|
).
|
||||||
|
Watches(
|
||||||
|
&sourcev1.Bucket{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(indexBucket)),
|
||||||
|
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
||||||
|
).
|
||||||
|
WatchesMetadata(
|
||||||
|
&corev1.ConfigMap{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(r.requestsForConfigDependency(indexConfigMap)),
|
||||||
|
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}, opts.WatchConfigsPredicate),
|
||||||
|
).
|
||||||
|
WatchesMetadata(
|
||||||
|
&corev1.Secret{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(r.requestsForConfigDependency(indexSecret)),
|
||||||
|
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}, opts.WatchConfigsPredicate),
|
||||||
|
)
|
||||||
|
|
||||||
|
if opts.WatchExternalArtifacts {
|
||||||
|
ctrlBuilder = ctrlBuilder.Watches(
|
||||||
|
&sourcev1.ExternalArtifact{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(indexExternalArtifact)),
|
||||||
|
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrlBuilder.WithOptions(controller.Options{RateLimiter: opts.RateLimiter}).Complete(r)
|
||||||
|
}
|
|
@ -87,7 +87,7 @@ stringData:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -115,6 +115,15 @@ stringData:
|
||||||
|
|
||||||
g.Expect(resultK.Status.LastAppliedOriginRevision).To(Equal("orev"))
|
g.Expect(resultK.Status.LastAppliedOriginRevision).To(Equal("orev"))
|
||||||
|
|
||||||
|
g.Expect(resultK.Status.History).To(HaveLen(1))
|
||||||
|
g.Expect(resultK.Status.History[0].Digest).ToNot(BeEmpty())
|
||||||
|
g.Expect(resultK.Status.History[0].TotalReconciliations).To(BeEquivalentTo(1))
|
||||||
|
g.Expect(resultK.Status.History[0].FirstReconciled.Time).ToNot(BeZero())
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciled.Time).ToNot(BeZero())
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciledStatus).To(Equal(meta.ReconciliationSucceededReason))
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciledDuration.Duration).To(BeNumerically(">", 0))
|
||||||
|
g.Expect(resultK.Status.History[0].Metadata).To(ContainElements(revision, "orev"))
|
||||||
|
|
||||||
events := getEvents(kustomizationKey.Name, nil)
|
events := getEvents(kustomizationKey.Name, nil)
|
||||||
g.Expect(events).To(Not(BeEmpty()))
|
g.Expect(events).To(Not(BeEmpty()))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/fluxcd/pkg/apis/kustomize"
|
||||||
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
"github.com/fluxcd/pkg/testserver"
|
||||||
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestKustomizationReconciler_MultiplePatchDelete tests the handling of multiple
|
||||||
|
// $patch: delete directives in strategic merge patches.
|
||||||
|
// This test ensures that the controller properly handles scenarios where multiple
|
||||||
|
// resources are deleted using a single patch specification.
|
||||||
|
func TestKustomizationReconciler_MultiplePatchDelete(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
id := "multi-patch-delete-" + randStringRunes(5)
|
||||||
|
revision := "v1.0.0"
|
||||||
|
|
||||||
|
err := createNamespace(id)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
|
||||||
|
|
||||||
|
err = createKubeConfigSecret(id)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
|
||||||
|
|
||||||
|
// Create test files with multiple ConfigMaps
|
||||||
|
manifests := func(name string, data string) []testserver.File {
|
||||||
|
return []testserver.File{
|
||||||
|
{
|
||||||
|
Name: "configmaps.yaml",
|
||||||
|
Body: `---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cm1
|
||||||
|
namespace: ` + name + `
|
||||||
|
data:
|
||||||
|
key: ` + data + `1
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cm2
|
||||||
|
namespace: ` + name + `
|
||||||
|
data:
|
||||||
|
key: ` + data + `2
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cm3
|
||||||
|
namespace: ` + name + `
|
||||||
|
data:
|
||||||
|
key: ` + data + `3
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact, err := testServer.ArtifactFromFiles(manifests(id, randStringRunes(5)))
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
repositoryName := types.NamespacedName{
|
||||||
|
Name: randStringRunes(5),
|
||||||
|
Namespace: id,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = applyGitRepository(repositoryName, artifact, revision)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
kustomizationKey := types.NamespacedName{
|
||||||
|
Name: "patch-delete-" + randStringRunes(5),
|
||||||
|
Namespace: id,
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("multiple patch delete in single patch should work", func(t *testing.T) {
|
||||||
|
// This test verifies that multiple $patch: delete directives in a single patch work correctly
|
||||||
|
// Ref: https://github.com/fluxcd/kustomize-controller/issues/1306
|
||||||
|
kustomization := &kustomizev1.Kustomization{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kustomizationKey.Name,
|
||||||
|
Namespace: kustomizationKey.Namespace,
|
||||||
|
},
|
||||||
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
|
Path: "./",
|
||||||
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
|
SecretRef: &meta.SecretKeyReference{
|
||||||
|
Name: "kubeconfig",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||||
|
Name: repositoryName.Name,
|
||||||
|
Namespace: repositoryName.Namespace,
|
||||||
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
|
},
|
||||||
|
Prune: true,
|
||||||
|
Patches: []kustomize.Patch{
|
||||||
|
{
|
||||||
|
// Multiple $patch: delete in a single patch
|
||||||
|
Patch: `$patch: delete
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cm1
|
||||||
|
namespace: ` + id + `
|
||||||
|
---
|
||||||
|
$patch: delete
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cm2
|
||||||
|
namespace: ` + id + ``,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
|
||||||
|
|
||||||
|
// Wait for reconciliation and check that it succeeds without panic
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
var obj kustomizev1.Kustomization
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), &obj)
|
||||||
|
return obj.Status.LastAppliedRevision == revision
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
// Verify that only cm3 ConfigMap exists (cm1 and cm2 should be deleted)
|
||||||
|
var cm corev1.ConfigMap
|
||||||
|
err := k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm1", Namespace: id}, &cm)
|
||||||
|
g.Expect(err).To(HaveOccurred(), "cm1 should have been deleted")
|
||||||
|
|
||||||
|
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm2", Namespace: id}, &cm)
|
||||||
|
g.Expect(err).To(HaveOccurred(), "cm2 should have been deleted")
|
||||||
|
|
||||||
|
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm3", Namespace: id}, &cm)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "cm3 should still exist")
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
g.Expect(k8sClient.Delete(context.Background(), kustomization)).To(Succeed())
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), kustomization)
|
||||||
|
return apierrors.IsNotFound(err)
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("multiple patch delete in separate patches should work", func(t *testing.T) {
|
||||||
|
// This test verifies that separate patches (which was previously a workaround) still work correctly
|
||||||
|
kustomizationSeparate := &kustomizev1.Kustomization{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kustomizationKey.Name + "-separate",
|
||||||
|
Namespace: kustomizationKey.Namespace,
|
||||||
|
},
|
||||||
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
|
Path: "./",
|
||||||
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
|
SecretRef: &meta.SecretKeyReference{
|
||||||
|
Name: "kubeconfig",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||||
|
Name: repositoryName.Name,
|
||||||
|
Namespace: repositoryName.Namespace,
|
||||||
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
|
},
|
||||||
|
Prune: true,
|
||||||
|
Patches: []kustomize.Patch{
|
||||||
|
{
|
||||||
|
Patch: `$patch: delete
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cm1
|
||||||
|
namespace: ` + id + ``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Patch: `$patch: delete
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: cm2
|
||||||
|
namespace: ` + id + ``,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Expect(k8sClient.Create(context.Background(), kustomizationSeparate)).To(Succeed())
|
||||||
|
|
||||||
|
// Wait for successful reconciliation
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
var obj kustomizev1.Kustomization
|
||||||
|
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomizationSeparate), &obj)
|
||||||
|
return obj.Status.LastAppliedRevision == revision
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
|
||||||
|
// Verify that only cm3 ConfigMap exists
|
||||||
|
var cm corev1.ConfigMap
|
||||||
|
err := k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm1", Namespace: id}, &cm)
|
||||||
|
g.Expect(err).To(HaveOccurred(), "cm1 should have been deleted")
|
||||||
|
|
||||||
|
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm2", Namespace: id}, &cm)
|
||||||
|
g.Expect(err).To(HaveOccurred(), "cm2 should have been deleted")
|
||||||
|
|
||||||
|
err = k8sClient.Get(context.Background(), client.ObjectKey{Name: "cm3", Namespace: id}, &cm)
|
||||||
|
g.Expect(err).NotTo(HaveOccurred(), "cm3 should still exist")
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
g.Expect(k8sClient.Delete(context.Background(), kustomizationSeparate)).To(Succeed())
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
err := k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomizationSeparate), kustomizationSeparate)
|
||||||
|
return apierrors.IsNotFound(err)
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
})
|
||||||
|
}
|
|
@ -99,7 +99,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -227,7 +227,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -385,7 +385,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -91,7 +91,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -200,7 +200,7 @@ data:
|
||||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -270,7 +270,7 @@ func TestKustomizationReconciler_KustomizeTransformer(t *testing.T) {
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -393,7 +393,7 @@ func TestKustomizationReconciler_KustomizeTransformerFiles(t *testing.T) {
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -512,7 +512,7 @@ func TestKustomizationReconciler_FluxTransformers(t *testing.T) {
|
||||||
Interval: metav1.Duration{Duration: reconciliationInterval},
|
Interval: metav1.Duration{Duration: reconciliationInterval},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -80,7 +80,7 @@ func TestKustomizationReconciler_Validation(t *testing.T) {
|
||||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -120,7 +120,7 @@ stringData:
|
||||||
},
|
},
|
||||||
Spec: kustomizev1.KustomizationSpec{
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -269,7 +269,7 @@ metadata:
|
||||||
},
|
},
|
||||||
Spec: kustomizev1.KustomizationSpec{
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -426,7 +426,7 @@ data:
|
||||||
},
|
},
|
||||||
Spec: kustomizev1.KustomizationSpec{
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -532,7 +532,7 @@ metadata:
|
||||||
},
|
},
|
||||||
Spec: kustomizev1.KustomizationSpec{
|
Spec: kustomizev1.KustomizationSpec{
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -105,7 +105,7 @@ parameters:
|
||||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -136,6 +136,11 @@ parameters:
|
||||||
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
|
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
|
||||||
|
|
||||||
kstatusCheck.CheckErr(ctx, resultK)
|
kstatusCheck.CheckErr(ctx, resultK)
|
||||||
|
|
||||||
|
g.Expect(resultK.Status.History).To(HaveLen(1))
|
||||||
|
g.Expect(resultK.Status.History[0].TotalReconciliations).To(BeEquivalentTo(1))
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciledStatus).To(Equal(meta.ReconciliationSucceededReason))
|
||||||
|
g.Expect(resultK.Status.History[0].Metadata).To(ContainElements(revision))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("reports progressing status", func(t *testing.T) {
|
t.Run("reports progressing status", func(t *testing.T) {
|
||||||
|
@ -192,6 +197,11 @@ parameters:
|
||||||
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation - 1))
|
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation - 1))
|
||||||
|
|
||||||
kstatusCheck.CheckErr(ctx, resultK)
|
kstatusCheck.CheckErr(ctx, resultK)
|
||||||
|
|
||||||
|
g.Expect(resultK.Status.History).To(HaveLen(2))
|
||||||
|
g.Expect(resultK.Status.History[0].TotalReconciliations).To(BeEquivalentTo(1))
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciledStatus).To(Equal(meta.HealthCheckFailedReason))
|
||||||
|
g.Expect(resultK.Status.History[0].Metadata).To(ContainElements(revision))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("emits unhealthy event", func(t *testing.T) {
|
t.Run("emits unhealthy event", func(t *testing.T) {
|
||||||
|
@ -228,6 +238,11 @@ parameters:
|
||||||
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
|
g.Expect(resultK.Status.ObservedGeneration).To(BeIdenticalTo(resultK.Generation))
|
||||||
|
|
||||||
kstatusCheck.CheckErr(ctx, resultK)
|
kstatusCheck.CheckErr(ctx, resultK)
|
||||||
|
|
||||||
|
g.Expect(resultK.Status.History).To(HaveLen(2))
|
||||||
|
g.Expect(resultK.Status.History[0].TotalReconciliations).To(BeEquivalentTo(2))
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciledStatus).To(Equal(meta.ReconciliationSucceededReason))
|
||||||
|
g.Expect(resultK.Status.History[0].Metadata).To(ContainElements(revision))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("emits recovery event", func(t *testing.T) {
|
t.Run("emits recovery event", func(t *testing.T) {
|
||||||
|
@ -258,6 +273,11 @@ parameters:
|
||||||
g.Expect(resultK.Status.LastAttemptedRevision).To(BeIdenticalTo(resultK.Status.LastAppliedRevision))
|
g.Expect(resultK.Status.LastAttemptedRevision).To(BeIdenticalTo(resultK.Status.LastAppliedRevision))
|
||||||
|
|
||||||
kstatusCheck.CheckErr(ctx, resultK)
|
kstatusCheck.CheckErr(ctx, resultK)
|
||||||
|
|
||||||
|
g.Expect(resultK.Status.History).To(HaveLen(3))
|
||||||
|
g.Expect(resultK.Status.History[0].TotalReconciliations).To(BeEquivalentTo(1))
|
||||||
|
g.Expect(resultK.Status.History[0].LastReconciledStatus).To(Equal(meta.ReconciliationSucceededReason))
|
||||||
|
g.Expect(resultK.Status.History[0].Metadata).To(ContainElements(revision))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("emits event for the new revision", func(t *testing.T) {
|
t.Run("emits event for the new revision", func(t *testing.T) {
|
||||||
|
@ -331,7 +351,7 @@ data: {}
|
||||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||||
Path: "./",
|
Path: "./",
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -411,7 +431,7 @@ func TestKustomizationReconciler_RESTMapper(t *testing.T) {
|
||||||
Kind: sourcev1.GitRepositoryKind,
|
Kind: sourcev1.GitRepositoryKind,
|
||||||
},
|
},
|
||||||
KubeConfig: &meta.KubeConfigReference{
|
KubeConfig: &meta.KubeConfigReference{
|
||||||
SecretRef: meta.SecretKeyReference{
|
SecretRef: &meta.SecretKeyReference{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -37,6 +37,7 @@ import (
|
||||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||||
controllerLog "sigs.k8s.io/controller-runtime/pkg/log"
|
controllerLog "sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
@ -57,6 +58,7 @@ const (
|
||||||
reconciliationInterval = time.Second * 5
|
reconciliationInterval = time.Second * 5
|
||||||
vaultVersion = "1.13.2"
|
vaultVersion = "1.13.2"
|
||||||
overrideManagerName = "node-fetch"
|
overrideManagerName = "node-fetch"
|
||||||
|
sopsAgeSecret = "sops-age-secret"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -172,17 +174,21 @@ func TestMain(m *testing.M) {
|
||||||
kstatusInProgressCheck = kcheck.NewInProgressChecker(testEnv.Client)
|
kstatusInProgressCheck = kcheck.NewInProgressChecker(testEnv.Client)
|
||||||
kstatusInProgressCheck.DisableFetch = true
|
kstatusInProgressCheck.DisableFetch = true
|
||||||
reconciler = &KustomizationReconciler{
|
reconciler = &KustomizationReconciler{
|
||||||
ControllerName: controllerName,
|
ControllerName: controllerName,
|
||||||
Client: testEnv,
|
StatusManager: fmt.Sprintf("gotk-%s", controllerName),
|
||||||
Mapper: testEnv.GetRESTMapper(),
|
Client: testEnv,
|
||||||
APIReader: testEnv,
|
Mapper: testEnv.GetRESTMapper(),
|
||||||
EventRecorder: testEnv.GetEventRecorderFor(controllerName),
|
APIReader: testEnv,
|
||||||
Metrics: testMetricsH,
|
EventRecorder: testEnv.GetEventRecorderFor(controllerName),
|
||||||
ConcurrentSSA: 4,
|
Metrics: testMetricsH,
|
||||||
DisallowedFieldManagers: []string{overrideManagerName},
|
DependencyRequeueInterval: 2 * time.Second,
|
||||||
|
ConcurrentSSA: 4,
|
||||||
|
DisallowedFieldManagers: []string{overrideManagerName},
|
||||||
|
SOPSAgeSecret: sopsAgeSecret,
|
||||||
}
|
}
|
||||||
if err := (reconciler).SetupWithManager(ctx, testEnv, KustomizationReconcilerOptions{
|
if err := (reconciler).SetupWithManager(ctx, testEnv, KustomizationReconcilerOptions{
|
||||||
DependencyRequeueInterval: 2 * time.Second,
|
WatchConfigsPredicate: predicate.Not(predicate.Funcs{}),
|
||||||
|
WatchExternalArtifacts: true,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
panic(fmt.Sprintf("Failed to start KustomizationReconciler: %v", err))
|
panic(fmt.Sprintf("Failed to start KustomizationReconciler: %v", err))
|
||||||
}
|
}
|
||||||
|
@ -327,7 +333,7 @@ func applyGitRepository(objKey client.ObjectKey, artifactName string,
|
||||||
Reason: sourcev1.GitOperationSucceedReason,
|
Reason: sourcev1.GitOperationSucceedReason,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Artifact: &sourcev1.Artifact{
|
Artifact: &meta.Artifact{
|
||||||
Path: url,
|
Path: url,
|
||||||
URL: url,
|
URL: url,
|
||||||
Revision: revision,
|
Revision: revision,
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- secret.yaml
|
|
@ -0,0 +1,23 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: global-age-secret
|
||||||
|
namespace: default
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
key: ENC[AES256_GCM,data:5d9WYyV8eyrOhF/m,iv:wuxE+q4pB+2cXBLcOy4/eZFSteLXJJDEI001UFAPd3A=,tag:EyM2zosBOv5/DnZMUqyNJg==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1henwn645drkd3fa34t27t2w2x0nsgw3w4h62gmg5x5xflyjpy38s5cncph
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhSEJIVUQrZXpkZmJ6ek1U
|
||||||
|
enNmL2cycGJVTUp0bGJBQmhzUms5eENWd1MwCjZtUjMvT28zWU8wVHArNDdyNG1x
|
||||||
|
RjJCK29jNEJ5bDc5M2pNVG0rcHhFQ2cKLS0tIDkzRk5zdTZ5ek4rNzNvT2l5VDJ1
|
||||||
|
Sk01a05sV094UjFVbkhsVUhaOFhWa3MKwVILC0MO4CPlK0kniPTxOgMxej+E1NJ3
|
||||||
|
d1vA+h/DFoHDV6fU63n/v0BLmi7q0x10pYj95u1Ef1cP24JC/G+M4g==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2025-07-06T17:19:51Z"
|
||||||
|
mac: ENC[AES256_GCM,data:5vkroTHj/9sLCEb+LHZEWwbrq9amLfU9QsDE6ZmpSDa/r7T2RGzX9cAhe73s2L7E5EZblsWOGLPdQCRXP/Llp19QzEU6dYs+n0IyFprjtYpL8VEB3S2aCPzdhOrN0o/pcHGmfvp4S9gXvwki1EIYhRL7ozBHNppxQGLOdVDigjg=,iv:dCzK0olxFn4QwknnYvO4LNo7SjuX04zF6saVRFQv7wY=,tag:GwL7WDw2IBxNUdGUBpBXEQ==,type:str]
|
||||||
|
encrypted_regex: ^(data|stringData)$
|
||||||
|
version: 3.10.2
|
|
@ -0,0 +1,3 @@
|
||||||
|
# created: 2025-07-06T17:30:37+01:00
|
||||||
|
# public key: age1henwn645drkd3fa34t27t2w2x0nsgw3w4h62gmg5x5xflyjpy38s5cncph
|
||||||
|
AGE-SECRET-KEY-10U7MAELH09KZU63F65P2TYLN7TQM5X6GSDDCQ4YMUGDS3DS6XZMSTYY2PN
|
|
@ -162,32 +162,30 @@ type Decryptor struct {
|
||||||
// decryptor.
|
// decryptor.
|
||||||
keyServices []keyservice.KeyServiceClient
|
keyServices []keyservice.KeyServiceClient
|
||||||
localServiceOnce sync.Once
|
localServiceOnce sync.Once
|
||||||
|
|
||||||
|
// sopsAgeSecret is the NamespacedName of the Secret containing
|
||||||
|
// a fallback SOPS age decryption key.
|
||||||
|
sopsAgeSecret *types.NamespacedName
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDecryptor creates a new Decryptor for the given kustomization.
|
// New creates a new Decryptor, with a temporary GnuPG
|
||||||
// gnuPGHome can be empty, in which case the systems' keyring is used.
|
|
||||||
func NewDecryptor(root string, client client.Client, kustomization *kustomizev1.Kustomization,
|
|
||||||
maxFileSize int64, gnuPGHome string, tokenCache *cache.TokenCache) *Decryptor {
|
|
||||||
return &Decryptor{
|
|
||||||
root: root,
|
|
||||||
client: client,
|
|
||||||
kustomization: kustomization,
|
|
||||||
maxFileSize: maxFileSize,
|
|
||||||
gnuPGHome: pgp.GnuPGHome(gnuPGHome),
|
|
||||||
tokenCache: tokenCache,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTempDecryptor creates a new Decryptor, with a temporary GnuPG
|
|
||||||
// home directory to Decryptor.ImportKeys() into.
|
// home directory to Decryptor.ImportKeys() into.
|
||||||
func NewTempDecryptor(root string, client client.Client, kustomization *kustomizev1.Kustomization,
|
func New(client client.Client, kustomization *kustomizev1.Kustomization, opts ...Option) (*Decryptor, func(), error) {
|
||||||
tokenCache *cache.TokenCache) (*Decryptor, func(), error) {
|
|
||||||
gnuPGHome, err := pgp.NewGnuPGHome()
|
gnuPGHome, err := pgp.NewGnuPGHome()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("cannot create decryptor: %w", err)
|
return nil, nil, fmt.Errorf("cannot create decryptor: %w", err)
|
||||||
}
|
}
|
||||||
cleanup := func() { _ = os.RemoveAll(gnuPGHome.String()) }
|
cleanup := func() { _ = os.RemoveAll(gnuPGHome.String()) }
|
||||||
return NewDecryptor(root, client, kustomization, maxEncryptedFileSize, gnuPGHome.String(), tokenCache), cleanup, nil
|
d := &Decryptor{
|
||||||
|
client: client,
|
||||||
|
kustomization: kustomization,
|
||||||
|
maxFileSize: maxEncryptedFileSize,
|
||||||
|
gnuPGHome: gnuPGHome,
|
||||||
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(d)
|
||||||
|
}
|
||||||
|
return d, cleanup, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEncryptedSecret checks if the given object is a Kubernetes Secret encrypted
|
// IsEncryptedSecret checks if the given object is a Kubernetes Secret encrypted
|
||||||
|
@ -210,16 +208,43 @@ func IsEncryptedSecret(object *unstructured.Unstructured) bool {
|
||||||
// For the import of PGP keys, the Decryptor must be configured with
|
// For the import of PGP keys, the Decryptor must be configured with
|
||||||
// an absolute GnuPG home directory path.
|
// an absolute GnuPG home directory path.
|
||||||
func (d *Decryptor) ImportKeys(ctx context.Context) error {
|
func (d *Decryptor) ImportKeys(ctx context.Context) error {
|
||||||
if d.kustomization.Spec.Decryption == nil || d.kustomization.Spec.Decryption.SecretRef == nil {
|
if d.kustomization.Spec.Decryption == nil ||
|
||||||
|
(d.kustomization.Spec.Decryption.SecretRef == nil && d.sopsAgeSecret == nil) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := d.kustomization.Spec.Decryption.Provider
|
provider := d.kustomization.Spec.Decryption.Provider
|
||||||
switch provider {
|
switch provider {
|
||||||
case DecryptionProviderSOPS:
|
case DecryptionProviderSOPS:
|
||||||
|
secretRef := d.kustomization.Spec.Decryption.SecretRef
|
||||||
|
|
||||||
|
// We handle the SOPS age global decryption separately, as most of the other
|
||||||
|
// decryption providers already support global decryption in other ways, and
|
||||||
|
// we don't want to introduce duplicate methods of achieving the same.
|
||||||
|
// Furthermore, allowing e.g. cloud provider credentials to be fetched
|
||||||
|
// from this global secret would prevent workload identity from working.
|
||||||
|
if secretRef == nil && d.sopsAgeSecret != nil {
|
||||||
|
var secret corev1.Secret
|
||||||
|
if err := d.client.Get(ctx, *d.sopsAgeSecret, &secret); err != nil {
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fmt.Errorf("cannot get %s SOPS age decryption Secret '%s': %w", provider, *d.sopsAgeSecret, err)
|
||||||
|
}
|
||||||
|
for name, value := range secret.Data {
|
||||||
|
if filepath.Ext(name) == DecryptionAgeExt {
|
||||||
|
if err := d.ageIdentities.Import(string(value)); err != nil {
|
||||||
|
return fmt.Errorf("failed to import '%s' data from %s SOPS age decryption Secret '%s': %w",
|
||||||
|
name, provider, *d.sopsAgeSecret, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
secretName := types.NamespacedName{
|
secretName := types.NamespacedName{
|
||||||
Namespace: d.kustomization.GetNamespace(),
|
Namespace: d.kustomization.GetNamespace(),
|
||||||
Name: d.kustomization.Spec.Decryption.SecretRef.Name,
|
Name: secretRef.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
var secret corev1.Secret
|
var secret corev1.Secret
|
||||||
|
@ -291,14 +316,17 @@ func (d *Decryptor) SetAuthOptions(ctx context.Context) {
|
||||||
|
|
||||||
switch d.kustomization.Spec.Decryption.Provider {
|
switch d.kustomization.Spec.Decryption.Provider {
|
||||||
case DecryptionProviderSOPS:
|
case DecryptionProviderSOPS:
|
||||||
var opts []auth.Option
|
opts := []auth.Option{
|
||||||
|
auth.WithClient(d.client),
|
||||||
|
}
|
||||||
|
|
||||||
if d.kustomization.Spec.Decryption.ServiceAccountName != "" {
|
saName := d.kustomization.Spec.Decryption.ServiceAccountName
|
||||||
serviceAccount := types.NamespacedName{
|
if saName == "" {
|
||||||
Name: d.kustomization.Spec.Decryption.ServiceAccountName,
|
saName = auth.GetDefaultDecryptionServiceAccount()
|
||||||
Namespace: d.kustomization.GetNamespace(),
|
}
|
||||||
}
|
if saName != "" {
|
||||||
opts = append(opts, auth.WithServiceAccount(serviceAccount, d.client))
|
opts = append(opts, auth.WithServiceAccountName(saName))
|
||||||
|
opts = append(opts, auth.WithServiceAccountNamespace(d.kustomization.GetNamespace()))
|
||||||
}
|
}
|
||||||
|
|
||||||
involvedObject := cache.InvolvedObject{
|
involvedObject := cache.InvolvedObject{
|
||||||
|
|
|
@ -376,7 +376,7 @@ clientSecret: some-client-secret`),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
d, cleanup, err := NewTempDecryptor("", cb.Build(), &kustomization, nil)
|
d, cleanup, err := New(cb.Build(), &kustomization)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
|
||||||
Provider: DecryptionProviderSOPS,
|
Provider: DecryptionProviderSOPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
|
d, cleanup, err := New(fake.NewClientBuilder().Build(), kus)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
@ -646,7 +646,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
|
||||||
Provider: DecryptionProviderSOPS,
|
Provider: DecryptionProviderSOPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
|
d, cleanup, err := New(fake.NewClientBuilder().Build(), kus)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
@ -681,7 +681,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
|
||||||
Provider: DecryptionProviderSOPS,
|
Provider: DecryptionProviderSOPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
|
d, cleanup, err := New(fake.NewClientBuilder().Build(), kus)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
@ -716,7 +716,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
|
||||||
Provider: DecryptionProviderSOPS,
|
Provider: DecryptionProviderSOPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
|
d, cleanup, err := New(fake.NewClientBuilder().Build(), kus)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
@ -765,7 +765,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
|
||||||
t.Run("nil resource", func(t *testing.T) {
|
t.Run("nil resource", func(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kustomization.DeepCopy(), nil)
|
d, cleanup, err := New(fake.NewClientBuilder().Build(), kustomization.DeepCopy())
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
@ -777,7 +777,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
|
||||||
t.Run("no decryption spec", func(t *testing.T) {
|
t.Run("no decryption spec", func(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kustomization.DeepCopy(), nil)
|
d, cleanup, err := New(fake.NewClientBuilder().Build(), kustomization.DeepCopy())
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
@ -793,7 +793,7 @@ func TestDecryptor_DecryptResource(t *testing.T) {
|
||||||
kus.Spec.Decryption = &kustomizev1.Decryption{
|
kus.Spec.Decryption = &kustomizev1.Decryption{
|
||||||
Provider: "not-supported",
|
Provider: "not-supported",
|
||||||
}
|
}
|
||||||
d, cleanup, err := NewTempDecryptor("", fake.NewClientBuilder().Build(), kus, nil)
|
d, cleanup, err := New(fake.NewClientBuilder().Build(), kus)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
t.Cleanup(cleanup)
|
t.Cleanup(cleanup)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package decryptor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
|
||||||
|
"github.com/fluxcd/pkg/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Option is a functional option for configuring the Decryptor.
|
||||||
|
type Option func(o *Decryptor)
|
||||||
|
|
||||||
|
// WithRoot sets the root directory for the Decryptor.
|
||||||
|
func WithRoot(root string) Option {
|
||||||
|
return func(o *Decryptor) {
|
||||||
|
o.root = root
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTokenCache sets the token cache for the Decryptor.
|
||||||
|
func WithTokenCache(tokenCache cache.TokenCache) Option {
|
||||||
|
return func(o *Decryptor) {
|
||||||
|
o.tokenCache = &tokenCache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSOPSAgeSecret sets the SOPSAgeSecret for the Decryptor.
|
||||||
|
func WithSOPSAgeSecret(name, namespace string) Option {
|
||||||
|
return func(o *Decryptor) {
|
||||||
|
o.sopsAgeSecret = &types.NamespacedName{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,9 +48,17 @@ const (
|
||||||
// but is missing from the input vars.
|
// but is missing from the input vars.
|
||||||
StrictPostBuildSubstitutions = "StrictPostBuildSubstitutions"
|
StrictPostBuildSubstitutions = "StrictPostBuildSubstitutions"
|
||||||
|
|
||||||
// GroupChangelog controls groups kubernetes objects names on log output
|
// GroupChangeLog controls whether to group Kubernetes objects names in log output
|
||||||
// reduces cardinality of logs when logging to elasticsearch
|
// to reduce cardinality of logs.
|
||||||
GroupChangeLog = "GroupChangeLog"
|
GroupChangeLog = "GroupChangeLog"
|
||||||
|
|
||||||
|
// AdditiveCELDependencyCheck controls whether the CEL dependency check
|
||||||
|
// should be additive, meaning that the built-in readiness check will
|
||||||
|
// be added to the user-defined CEL expressions.
|
||||||
|
AdditiveCELDependencyCheck = "AdditiveCELDependencyCheck"
|
||||||
|
|
||||||
|
// ExternalArtifact controls whether the ExternalArtifact source type is enabled.
|
||||||
|
ExternalArtifact = "ExternalArtifact"
|
||||||
)
|
)
|
||||||
|
|
||||||
var features = map[string]bool{
|
var features = map[string]bool{
|
||||||
|
@ -69,6 +77,12 @@ var features = map[string]bool{
|
||||||
// GroupChangeLog
|
// GroupChangeLog
|
||||||
// opt-in from v1.5
|
// opt-in from v1.5
|
||||||
GroupChangeLog: false,
|
GroupChangeLog: false,
|
||||||
|
// AdditiveCELDependencyCheck
|
||||||
|
// opt-in from v1.7
|
||||||
|
AdditiveCELDependencyCheck: false,
|
||||||
|
// ExternalArtifact
|
||||||
|
// opt-in from v1.7
|
||||||
|
ExternalArtifact: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// Namespace returns the namespace where the controller is running.
|
||||||
|
func Namespace() string {
|
||||||
|
return os.Getenv("RUNTIME_NAMESPACE")
|
||||||
|
}
|
|
@ -17,11 +17,25 @@ limitations under the License.
|
||||||
package awskms
|
package awskms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// arnRegex matches an AWS ARN, for example:
|
||||||
|
// "arn:aws:kms:us-west-2:107501996527:key/612d5f0p-p1l3-45e6-aca6-a5b005693a48".
|
||||||
|
// The regex matches both KMS keys and aliases, and supports different AWS partition names (aws, aws-cn, aws-us-gov).
|
||||||
|
//
|
||||||
|
// Copied from SOPS:
|
||||||
|
// https://github.com/getsops/sops/blob/b2edaade23453c8774fc28ec491ddbe2b9a4c994/kms/keysource.go#L30-L32
|
||||||
|
//
|
||||||
|
// ref:
|
||||||
|
// https://docs.aws.amazon.com/IAM/latest/UserGuide/reference-arns.html
|
||||||
|
var arnRegex = regexp.MustCompile(`^arn:aws[\w-]*:kms:(.+):[0-9]+:(key|alias)/.+$`)
|
||||||
|
|
||||||
// GetRegionFromKMSARN extracts the region from a KMS ARN.
|
// GetRegionFromKMSARN extracts the region from a KMS ARN.
|
||||||
func GetRegionFromKMSARN(arn string) string {
|
func GetRegionFromKMSARN(arn string) string {
|
||||||
arn = strings.TrimPrefix(arn, "arn:aws:kms:")
|
m := arnRegex.FindStringSubmatch(arn)
|
||||||
return strings.SplitN(arn, ":", 2)[0]
|
if m == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return m[1]
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,70 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetRegionFromKMSARN(t *testing.T) {
|
func TestGetRegionFromKMSARN(t *testing.T) {
|
||||||
g := NewWithT(t)
|
for _, tt := range []struct {
|
||||||
|
arn string
|
||||||
arn := "arn:aws:kms:us-east-1:211125720409:key/mrk-3179bb7e88bc42ffb1a27d5038ceea25"
|
expected string
|
||||||
|
}{
|
||||||
region := awskms.GetRegionFromKMSARN(arn)
|
{
|
||||||
g.Expect(region).To(Equal("us-east-1"))
|
arn: "arn:aws:kms:us-west-2:107501996527:key/612d5f0p-p1l3-45e6-aca6-a5b005693a48",
|
||||||
|
expected: "us-west-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws-cn:kms:cn-north-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab",
|
||||||
|
expected: "cn-north-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws-us-gov:kms:us-gov-west-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab",
|
||||||
|
expected: "us-gov-west-1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:kms:us-west-2:107501996527:alias/my-key-alias",
|
||||||
|
expected: "us-west-2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:kms:us-west-2:107501996527:key/",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:kms:us-west-2:107501996527:alias/",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "not-an-arn",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:s3:::my-bucket",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:iam::123456789012:user/David",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:lambda:us-west-2:123456789012:function:my-function",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:dynamodb:us-west-2:123456789012:table/my-table",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:rds:us-west-2:123456789012:db:my-database",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arn: "arn:aws:sns:us-west-2:123456789012:my-topic",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tt.arn, func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
g.Expect(awskms.GetRegionFromKMSARN(tt.arn)).To(Equal(tt.expected))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
129
main.go
129
main.go
|
@ -55,6 +55,7 @@ import (
|
||||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||||
"github.com/fluxcd/kustomize-controller/internal/controller"
|
"github.com/fluxcd/kustomize-controller/internal/controller"
|
||||||
"github.com/fluxcd/kustomize-controller/internal/features"
|
"github.com/fluxcd/kustomize-controller/internal/features"
|
||||||
|
intruntime "github.com/fluxcd/kustomize-controller/internal/runtime"
|
||||||
// +kubebuilder:scaffold:imports
|
// +kubebuilder:scaffold:imports
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -79,26 +80,29 @@ func main() {
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
metricsAddr string
|
metricsAddr string
|
||||||
eventsAddr string
|
eventsAddr string
|
||||||
healthAddr string
|
healthAddr string
|
||||||
concurrent int
|
concurrent int
|
||||||
concurrentSSA int
|
concurrentSSA int
|
||||||
requeueDependency time.Duration
|
requeueDependency time.Duration
|
||||||
clientOptions runtimeClient.Options
|
clientOptions runtimeClient.Options
|
||||||
kubeConfigOpts runtimeClient.KubeConfigOptions
|
kubeConfigOpts runtimeClient.KubeConfigOptions
|
||||||
logOptions logger.Options
|
logOptions logger.Options
|
||||||
leaderElectionOptions leaderelection.Options
|
leaderElectionOptions leaderelection.Options
|
||||||
rateLimiterOptions runtimeCtrl.RateLimiterOptions
|
rateLimiterOptions runtimeCtrl.RateLimiterOptions
|
||||||
watchOptions runtimeCtrl.WatchOptions
|
watchOptions runtimeCtrl.WatchOptions
|
||||||
intervalJitterOptions jitter.IntervalOptions
|
intervalJitterOptions jitter.IntervalOptions
|
||||||
aclOptions acl.Options
|
aclOptions acl.Options
|
||||||
noRemoteBases bool
|
noRemoteBases bool
|
||||||
httpRetry int
|
httpRetry int
|
||||||
defaultServiceAccount string
|
defaultServiceAccount string
|
||||||
featureGates feathelper.FeatureGates
|
defaultDecryptionServiceAccount string
|
||||||
disallowedFieldManagers []string
|
defaultKubeConfigServiceAccount string
|
||||||
tokenCacheOptions pkgcache.TokenFlags
|
sopsAgeSecret string
|
||||||
|
featureGates feathelper.FeatureGates
|
||||||
|
disallowedFieldManagers []string
|
||||||
|
tokenCacheOptions pkgcache.TokenFlags
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||||
|
@ -110,7 +114,10 @@ func main() {
|
||||||
flag.BoolVar(&noRemoteBases, "no-remote-bases", false,
|
flag.BoolVar(&noRemoteBases, "no-remote-bases", false,
|
||||||
"Disallow remote bases usage in Kustomize overlays. When this flag is enabled, all resources must refer to local files included in the source artifact.")
|
"Disallow remote bases usage in Kustomize overlays. When this flag is enabled, all resources must refer to local files included in the source artifact.")
|
||||||
flag.IntVar(&httpRetry, "http-retry", 9, "The maximum number of retries when failing to fetch artifacts over HTTP.")
|
flag.IntVar(&httpRetry, "http-retry", 9, "The maximum number of retries when failing to fetch artifacts over HTTP.")
|
||||||
flag.StringVar(&defaultServiceAccount, "default-service-account", "", "Default service account used for impersonation.")
|
flag.StringVar(&defaultServiceAccount, auth.ControllerFlagDefaultServiceAccount, "", "Default service account used for impersonation.")
|
||||||
|
flag.StringVar(&defaultDecryptionServiceAccount, auth.ControllerFlagDefaultDecryptionServiceAccount, "", "Default service account used for decryption.")
|
||||||
|
flag.StringVar(&defaultKubeConfigServiceAccount, auth.ControllerFlagDefaultKubeConfigServiceAccount, "", "Default service account used for kubeconfig.")
|
||||||
|
flag.StringVar(&sopsAgeSecret, "sops-age-secret", "", "The name of a Kubernetes secret in the RUNTIME_NAMESPACE containing a SOPS age decryption key for fallback usage.")
|
||||||
flag.StringArrayVar(&disallowedFieldManagers, "override-manager", []string{}, "Field manager disallowed to perform changes on managed resources.")
|
flag.StringArrayVar(&disallowedFieldManagers, "override-manager", []string{}, "Field manager disallowed to perform changes on managed resources.")
|
||||||
|
|
||||||
clientOptions.BindFlags(flag.CommandLine)
|
clientOptions.BindFlags(flag.CommandLine)
|
||||||
|
@ -143,6 +150,20 @@ func main() {
|
||||||
auth.EnableObjectLevelWorkloadIdentity()
|
auth.EnableObjectLevelWorkloadIdentity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: defaultServiceAccount is used for regular impersonation, not workload identity lockdown
|
||||||
|
|
||||||
|
if defaultDecryptionServiceAccount != "" {
|
||||||
|
auth.SetDefaultDecryptionServiceAccount(defaultDecryptionServiceAccount)
|
||||||
|
}
|
||||||
|
if defaultKubeConfigServiceAccount != "" {
|
||||||
|
auth.SetDefaultKubeConfigServiceAccount(defaultKubeConfigServiceAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth.InconsistentObjectLevelConfiguration() {
|
||||||
|
setupLog.Error(auth.ErrInconsistentObjectLevelConfiguration, "invalid configuration")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
if err := intervalJitterOptions.SetGlobalJitter(nil); err != nil {
|
if err := intervalJitterOptions.SetGlobalJitter(nil); err != nil {
|
||||||
setupLog.Error(err, "unable to set global jitter")
|
setupLog.Error(err, "unable to set global jitter")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -150,7 +171,7 @@ func main() {
|
||||||
|
|
||||||
watchNamespace := ""
|
watchNamespace := ""
|
||||||
if !watchOptions.AllNamespaces {
|
if !watchOptions.AllNamespaces {
|
||||||
watchNamespace = os.Getenv("RUNTIME_NAMESPACE")
|
watchNamespace = intruntime.Namespace()
|
||||||
}
|
}
|
||||||
|
|
||||||
watchSelector, err := runtimeCtrl.GetWatchSelector(watchOptions)
|
watchSelector, err := runtimeCtrl.GetWatchSelector(watchOptions)
|
||||||
|
@ -159,6 +180,12 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchConfigsPredicate, err := runtimeCtrl.GetWatchConfigsPredicate(watchOptions)
|
||||||
|
if err != nil {
|
||||||
|
setupLog.Error(err, "unable to configure watch configs label selector for controller")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
var disableCacheFor []ctrlclient.Object
|
var disableCacheFor []ctrlclient.Object
|
||||||
shouldCache, err := features.Enabled(features.CacheSecretsAndConfigMaps)
|
shouldCache, err := features.Enabled(features.CacheSecretsAndConfigMaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -255,6 +282,18 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
additiveCELDependencyCheck, err := features.Enabled(features.AdditiveCELDependencyCheck)
|
||||||
|
if err != nil {
|
||||||
|
setupLog.Error(err, "unable to check feature gate "+features.AdditiveCELDependencyCheck)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
allowExternalArtifact, err := features.Enabled(features.ExternalArtifact)
|
||||||
|
if err != nil {
|
||||||
|
setupLog.Error(err, "unable to check feature gate "+features.ExternalArtifact)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
var tokenCache *pkgcache.TokenCache
|
var tokenCache *pkgcache.TokenCache
|
||||||
if tokenCacheOptions.MaxSize > 0 {
|
if tokenCacheOptions.MaxSize > 0 {
|
||||||
var err error
|
var err error
|
||||||
|
@ -269,27 +308,33 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = (&controller.KustomizationReconciler{
|
if err = (&controller.KustomizationReconciler{
|
||||||
ControllerName: controllerName,
|
AdditiveCELDependencyCheck: additiveCELDependencyCheck,
|
||||||
DefaultServiceAccount: defaultServiceAccount,
|
AllowExternalArtifact: allowExternalArtifact,
|
||||||
Client: mgr.GetClient(),
|
APIReader: mgr.GetAPIReader(),
|
||||||
Mapper: restMapper,
|
ArtifactFetchRetries: httpRetry,
|
||||||
APIReader: mgr.GetAPIReader(),
|
Client: mgr.GetClient(),
|
||||||
Metrics: metricsH,
|
ClusterReader: clusterReader,
|
||||||
EventRecorder: eventRecorder,
|
ConcurrentSSA: concurrentSSA,
|
||||||
NoCrossNamespaceRefs: aclOptions.NoCrossNamespaceRefs,
|
ControllerName: controllerName,
|
||||||
NoRemoteBases: noRemoteBases,
|
DefaultServiceAccount: defaultServiceAccount,
|
||||||
FailFast: failFast,
|
DependencyRequeueInterval: requeueDependency,
|
||||||
ConcurrentSSA: concurrentSSA,
|
DisallowedFieldManagers: disallowedFieldManagers,
|
||||||
KubeConfigOpts: kubeConfigOpts,
|
EventRecorder: eventRecorder,
|
||||||
ClusterReader: clusterReader,
|
FailFast: failFast,
|
||||||
DisallowedFieldManagers: disallowedFieldManagers,
|
GroupChangeLog: groupChangeLog,
|
||||||
StrictSubstitutions: strictSubstitutions,
|
KubeConfigOpts: kubeConfigOpts,
|
||||||
GroupChangeLog: groupChangeLog,
|
Mapper: restMapper,
|
||||||
TokenCache: tokenCache,
|
Metrics: metricsH,
|
||||||
|
NoCrossNamespaceRefs: aclOptions.NoCrossNamespaceRefs,
|
||||||
|
NoRemoteBases: noRemoteBases,
|
||||||
|
SOPSAgeSecret: sopsAgeSecret,
|
||||||
|
StatusManager: fmt.Sprintf("gotk-%s", controllerName),
|
||||||
|
StrictSubstitutions: strictSubstitutions,
|
||||||
|
TokenCache: tokenCache,
|
||||||
}).SetupWithManager(ctx, mgr, controller.KustomizationReconcilerOptions{
|
}).SetupWithManager(ctx, mgr, controller.KustomizationReconcilerOptions{
|
||||||
DependencyRequeueInterval: requeueDependency,
|
RateLimiter: runtimeCtrl.GetRateLimiter(rateLimiterOptions),
|
||||||
HTTPRetry: httpRetry,
|
WatchConfigsPredicate: watchConfigsPredicate,
|
||||||
RateLimiter: runtimeCtrl.GetRateLimiter(rateLimiterOptions),
|
WatchExternalArtifacts: allowExternalArtifact,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", controllerName)
|
setupLog.Error(err, "unable to create controller", "controller", controllerName)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
FROM gcr.io/oss-fuzz-base/base-builder-go
|
FROM gcr.io/oss-fuzz-base/base-builder-go
|
||||||
|
|
||||||
RUN wget https://go.dev/dl/go1.24.0.linux-amd64.tar.gz \
|
RUN wget https://go.dev/dl/go1.25.0.linux-amd64.tar.gz \
|
||||||
&& mkdir temp-go \
|
&& mkdir temp-go \
|
||||||
&& rm -rf /root/.go/* \
|
&& rm -rf /root/.go/* \
|
||||||
&& tar -C temp-go/ -xzf go1.24.0.linux-amd64.tar.gz \
|
&& tar -C temp-go/ -xzf go1.25.0.linux-amd64.tar.gz \
|
||||||
&& mv temp-go/go/* /root/.go/
|
&& mv temp-go/go/* /root/.go/
|
||||||
|
|
||||||
ENV SRC=$GOPATH/src/github.com/fluxcd/kustomize-controller
|
ENV SRC=$GOPATH/src/github.com/fluxcd/kustomize-controller
|
||||||
|
|
Loading…
Reference in New Issue