Compare commits
40 Commits
api/v0.41.
...
main
Author | SHA1 | Date |
---|---|---|
|
6243cf04cd | |
|
b1c0cad5d8 | |
|
47cc2cb901 | |
|
8dad1fd2da | |
|
e1fae45113 | |
|
4f65ce9f5b | |
|
cfbdf5c756 | |
|
e954114e1a | |
|
3576ac8bc7 | |
|
1264b490cc | |
|
f62fa803ef | |
|
efa9671ebc | |
|
e4ed952724 | |
|
6955deae42 | |
|
57516b14f7 | |
|
f584731506 | |
|
91bbe7491f | |
|
9b8f0a6234 | |
|
8c21b03941 | |
|
3bff81a4e0 | |
|
0e29d5342b | |
|
03080bae28 | |
|
b81e735bae | |
|
8939b7b5b3 | |
|
ecaa7e7b14 | |
|
458e0338c3 | |
|
f1a92cb661 | |
|
7975a00bd1 | |
|
7bd947ca9d | |
|
4ff17e6807 | |
|
aedbb03c3e | |
|
ad9486eb8d | |
|
b3b47761c6 | |
|
af48849cc5 | |
|
ee384d74dd | |
|
e7d7d32d93 | |
|
c77a9799fb | |
|
fd132e2846 | |
|
124fd9fe8f | |
|
3999c651b1 |
|
@ -13,11 +13,11 @@ jobs:
|
||||||
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
|
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Create backport PRs
|
- name: Create backport PRs
|
||||||
uses: korthout/backport-action@436145e922f9561fc5ea157ff406f21af2d6b363 # v3.2.0
|
uses: korthout/backport-action@ca4972adce8039ff995e618f5fc02d1b7961f27a # v3.3.0
|
||||||
# xref: https://github.com/korthout/backport-action#inputs
|
# xref: https://github.com/korthout/backport-action#inputs
|
||||||
with:
|
with:
|
||||||
# Use token to allow workflows to be triggered for the created PR
|
# Use token to allow workflows to be triggered for the created PR
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
name: build
|
name: build
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches: [ 'main', 'release/**' ]
|
branches: [ 'main', 'release/**' ]
|
||||||
|
@ -12,35 +13,30 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.25.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
|
- name: Setup QEMU
|
||||||
|
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||||
|
- name: Setup Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: make test
|
run: make test
|
||||||
- name: Verify
|
- name: Verify
|
||||||
run: make verify
|
run: make verify
|
||||||
|
- name: Build multi-arch container image
|
||||||
kind-linux-arm64:
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
runs-on:
|
with:
|
||||||
group: "ARM64"
|
push: false
|
||||||
steps:
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
- name: checkout
|
context: .
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
file: ./Dockerfile
|
||||||
- name: Setup Go
|
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
tags: |
|
||||||
with:
|
${{ github.repository }}:latest
|
||||||
go-version: 1.24.x
|
|
||||||
cache-dependency-path: |
|
|
||||||
**/go.sum
|
|
||||||
**/go.mod
|
|
||||||
- name: Run tests
|
|
||||||
run: make test
|
|
||||||
env:
|
|
||||||
SKIP_COSIGN_VERIFICATION: true
|
|
||||||
- name: Verify
|
|
||||||
run: make verify
|
|
||||||
|
|
|
@ -11,11 +11,11 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.25.x
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
**/go.sum
|
**/go.sum
|
||||||
**/go.mod
|
**/go.mod
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
name: nightly
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
REPOSITORY: ${{ github.repository }}
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read # for actions/checkout to fetch code
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
||||||
- name: Setup QEMU
|
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
|
||||||
- name: Setup Docker Buildx
|
|
||||||
id: buildx
|
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
|
||||||
- name: Build multi-arch container image
|
|
||||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
|
||||||
with:
|
|
||||||
push: false
|
|
||||||
builder: ${{ steps.buildx.outputs.name }}
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
|
||||||
tags: |
|
|
||||||
${{ env.REPOSITORY }}:nightly
|
|
|
@ -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
|
||||||
|
|
|
@ -15,7 +15,7 @@ There are a number of dependencies required to be able to run the controller and
|
||||||
|
|
||||||
The following dependencies are also used by some of the `make` targets:
|
The following dependencies are also used by some of the `make` targets:
|
||||||
|
|
||||||
- `controller-gen` (v0.7.0)
|
- `controller-gen` (v0.19.0)
|
||||||
- `gen-crd-api-reference-docs` (v0.3.0)
|
- `gen-crd-api-reference-docs` (v0.3.0)
|
||||||
- `setup-envtest` (latest)
|
- `setup-envtest` (latest)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ If any of the above dependencies are not present on your system, the first invoc
|
||||||
## How to run the test suite
|
## How to run the test suite
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
* Go >= 1.24
|
* Go >= 1.25
|
||||||
|
|
||||||
You can run the test suite by simply doing
|
You can run the test suite by simply doing
|
||||||
|
|
||||||
|
|
44
Dockerfile
44
Dockerfile
|
@ -1,30 +1,16 @@
|
||||||
ARG BASE_VARIANT=alpine
|
ARG GO_VERSION=1.25
|
||||||
ARG GO_VERSION=1.24
|
|
||||||
ARG XX_VERSION=1.6.1
|
ARG XX_VERSION=1.6.1
|
||||||
|
|
||||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||||
|
|
||||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} AS gostable
|
# Docker buildkit multi-arch build requires golang alpine
|
||||||
|
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS builder
|
||||||
FROM gostable AS go-linux
|
|
||||||
|
|
||||||
# Build-base consists of build platform dependencies and xx.
|
|
||||||
# These will be used at current arch to yield execute the cross compilations.
|
|
||||||
FROM go-${TARGETOS} AS build-base
|
|
||||||
|
|
||||||
RUN apk add clang lld
|
|
||||||
|
|
||||||
|
# Copy the build utilities.
|
||||||
COPY --from=xx / /
|
COPY --from=xx / /
|
||||||
|
|
||||||
# build can still be cached at build platform architecture.
|
|
||||||
FROM build-base AS build
|
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
# Some dependencies have to installed for the target platform:
|
|
||||||
# https://github.com/tonistiigi/xx#go--cgo
|
|
||||||
RUN xx-apk add musl-dev gcc
|
|
||||||
|
|
||||||
# Configure workspace
|
# Configure workspace
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
|
|
||||||
|
@ -40,34 +26,22 @@ RUN go mod download
|
||||||
|
|
||||||
# Copy source code
|
# Copy source code
|
||||||
COPY main.go main.go
|
COPY main.go main.go
|
||||||
COPY pkg/ pkg/
|
|
||||||
COPY internal/ internal/
|
COPY internal/ internal/
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
# Reasons why CGO is in use:
|
# build without specifing the arch
|
||||||
# - The SHA1 implementation (sha1cd) used by go-git depends on CGO for
|
ENV CGO_ENABLED=0
|
||||||
# performance reasons. See: https://github.com/pjbgf/sha1cd/issues/15
|
RUN xx-go build -trimpath -a -o image-automation-controller main.go
|
||||||
ENV CGO_ENABLED=1
|
|
||||||
|
|
||||||
RUN export CGO_LDFLAGS="-static -fuse-ld=lld" && \
|
FROM alpine:3.22
|
||||||
xx-go build \
|
|
||||||
-ldflags "-s -w" \
|
|
||||||
-tags 'netgo,osusergo,static_build' \
|
|
||||||
-o /image-automation-controller -trimpath main.go;
|
|
||||||
|
|
||||||
# Ensure that the binary was cross-compiled correctly to the target platform.
|
|
||||||
RUN xx-verify --static /image-automation-controller
|
|
||||||
|
|
||||||
FROM alpine:3.21
|
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
RUN apk --no-cache add ca-certificates \
|
RUN apk --no-cache add ca-certificates \
|
||||||
&& update-ca-certificates
|
&& update-ca-certificates
|
||||||
|
|
||||||
# Copy over binary from build
|
COPY --from=builder /workspace/image-automation-controller /usr/local/bin/
|
||||||
COPY --from=build /image-automation-controller /usr/local/bin/
|
|
||||||
|
|
||||||
USER 65534:65534
|
USER 65534:65534
|
||||||
ENTRYPOINT [ "image-automation-controller" ]
|
ENTRYPOINT [ "image-automation-controller" ]
|
||||||
|
|
29
Makefile
29
Makefile
|
@ -15,9 +15,6 @@ BUILD_PLATFORMS ?= linux/amd64,linux/arm64,linux/arm/v7
|
||||||
# Allows for defining additional Go test args, e.g. '-tags integration'.
|
# Allows for defining additional Go test args, e.g. '-tags integration'.
|
||||||
GO_TEST_ARGS ?= -race
|
GO_TEST_ARGS ?= -race
|
||||||
|
|
||||||
# Defines whether cosign verification should be skipped.
|
|
||||||
SKIP_COSIGN_VERIFICATION ?= false
|
|
||||||
|
|
||||||
# Directory with versioned, downloaded things
|
# Directory with versioned, downloaded things
|
||||||
CACHE := cache
|
CACHE := cache
|
||||||
|
|
||||||
|
@ -37,16 +34,8 @@ BUILD_DIR := $(REPOSITORY_ROOT)/build
|
||||||
# each fuzzer should run for.
|
# each fuzzer should run for.
|
||||||
FUZZ_TIME ?= 1m
|
FUZZ_TIME ?= 1m
|
||||||
|
|
||||||
ifeq ($(shell uname -s),Darwin)
|
|
||||||
GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(shell uname -s),Linux)
|
|
||||||
GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build'
|
|
||||||
endif
|
|
||||||
|
|
||||||
# API (doc) generation utilities
|
# API (doc) generation utilities
|
||||||
CONTROLLER_GEN_VERSION ?= v0.16.1
|
CONTROLLER_GEN_VERSION ?= v0.19.0
|
||||||
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
|
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
|
||||||
|
|
||||||
# If gobin not set, create one on ./build and add to path.
|
# If gobin not set, create one on ./build and add to path.
|
||||||
|
@ -103,15 +92,10 @@ ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml:
|
||||||
curl -s --fail https://raw.githubusercontent.com/fluxcd/image-reflector-controller/${REFLECTOR_VER}/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml \
|
curl -s --fail https://raw.githubusercontent.com/fluxcd/image-reflector-controller/${REFLECTOR_VER}/config/crd/bases/image.toolkit.fluxcd.io_imagepolicies.yaml \
|
||||||
-o ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml
|
-o ${CACHE}/imagepolicies_${REFLECTOR_VER}.yaml
|
||||||
|
|
||||||
check-deps:
|
|
||||||
ifeq ($(shell uname -s),Darwin)
|
|
||||||
if ! command -v pkg-config &> /dev/null; then echo "pkg-config is required"; exit 1; fi
|
|
||||||
endif
|
|
||||||
|
|
||||||
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
|
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
|
||||||
test: tidy test-api test_deps generate fmt vet manifests api-docs install-envtest ## Run tests
|
test: tidy test-api test_deps generate fmt vet manifests api-docs install-envtest ## Run tests
|
||||||
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
|
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
|
||||||
go test $(GO_STATIC_FLAGS) $(GO_TEST_ARGS) ./... -coverprofile cover.out
|
go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
|
||||||
|
|
||||||
test-api: ## Run api tests
|
test-api: ## Run api tests
|
||||||
cd api; go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
|
cd api; go test $(GO_TEST_ARGS) ./... -coverprofile cover.out
|
||||||
|
@ -120,7 +104,7 @@ manager: generate fmt vet ## Build manager binary
|
||||||
go build -o $(BUILD_DIR)/bin/manager ./main.go
|
go build -o $(BUILD_DIR)/bin/manager ./main.go
|
||||||
|
|
||||||
run: generate fmt vet manifests # Run against the configured Kubernetes cluster in ~/.kube/config
|
run: generate fmt vet manifests # Run against the configured Kubernetes cluster in ~/.kube/config
|
||||||
go run $(GO_STATIC_FLAGS) ./main.go --log-level=${LOG_LEVEL} --log-encoding=console
|
go run ./main.go --log-level=${LOG_LEVEL} --log-encoding=console
|
||||||
|
|
||||||
install: manifests ## Install CRDs into a cluster
|
install: manifests ## Install CRDs into a cluster
|
||||||
kustomize build config/crd | kubectl apply -f -
|
kustomize build config/crd | kubectl apply -f -
|
||||||
|
@ -146,8 +130,8 @@ api-docs: gen-crd-api-reference-docs ## Generate API reference documentation
|
||||||
$(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta2/image-automation.md
|
$(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta2/image-automation.md
|
||||||
|
|
||||||
tidy: ## Run go mod tidy
|
tidy: ## Run go mod tidy
|
||||||
cd api; rm -f go.sum; go mod tidy -compat=1.24
|
cd api; rm -f go.sum; go mod tidy -compat=1.25
|
||||||
rm -f go.sum; go mod tidy -compat=1.24
|
rm -f go.sum; go mod tidy -compat=1.25
|
||||||
|
|
||||||
fmt: ## Run go fmt against code
|
fmt: ## Run go fmt against code
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
|
@ -236,9 +220,6 @@ rm -rf $$TMP_DIR ;\
|
||||||
}
|
}
|
||||||
endef
|
endef
|
||||||
|
|
||||||
update-attributions:
|
|
||||||
./hack/update-attributions.sh
|
|
||||||
|
|
||||||
verify:
|
verify:
|
||||||
ifneq (, $(shell git status --porcelain --untracked-files=no))
|
ifneq (, $(shell git status --porcelain --untracked-files=no))
|
||||||
@{ \
|
@{ \
|
||||||
|
|
30
api/go.mod
30
api/go.mod
|
@ -1,32 +1,34 @@
|
||||||
module github.com/fluxcd/image-automation-controller/api
|
module github.com/fluxcd/image-automation-controller/api
|
||||||
|
|
||||||
go 1.24.0
|
go 1.25.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0
|
github.com/fluxcd/pkg/apis/meta v1.20.0
|
||||||
github.com/fluxcd/source-controller/api v1.6.1
|
github.com/fluxcd/source-controller/api v1.6.2
|
||||||
k8s.io/apimachinery v0.33.0
|
k8s.io/apimachinery v0.34.0
|
||||||
sigs.k8s.io/controller-runtime v0.21.0
|
sigs.k8s.io/controller-runtime v0.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0 // indirect
|
github.com/fluxcd/pkg/apis/acl v0.7.0 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||||
github.com/go-logr/logr v1.4.2 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.7 // indirect
|
||||||
|
github.com/stretchr/testify v1.11.1 // indirect
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
golang.org/x/net v0.40.0 // indirect
|
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||||
golang.org/x/text v0.25.0 // indirect
|
golang.org/x/net v0.43.0 // indirect
|
||||||
|
golang.org/x/text v0.28.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect
|
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
||||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
75
api/go.sum
75
api/go.sum
|
@ -4,19 +4,18 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0=
|
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ=
|
github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg=
|
github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
|
github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
|
||||||
github.com/fluxcd/source-controller/api v1.6.1 h1:ZPTA9lNzBYHmwHfFX978qb8xVkdnQZHF1ggo6BoFm4w=
|
github.com/fluxcd/source-controller/api v1.6.2 h1:UmodAeqLIeF29HdTqf2GiacZyO+hJydJlepDaYsMvhc=
|
||||||
github.com/fluxcd/source-controller/api v1.6.1/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
|
github.com/fluxcd/source-controller/api v1.6.2/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
|
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
@ -33,8 +32,9 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
|
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
|
||||||
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||||
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
|
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
|
||||||
|
@ -44,16 +44,18 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
@ -63,26 +65,26 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -94,22 +96,21 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
|
k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
|
||||||
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
|
k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
|
||||||
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
|
k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
|
||||||
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
|
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
|
sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
|
sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||||
|
|
|
@ -14,12 +14,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Package v1beta1 contains API types for the image API group, version
|
// Package v1beta1 contains API types for the image v1beta1 API group
|
||||||
// v1beta1. The types here are concerned with automated updates to
|
//
|
||||||
// git, based on metadata from OCI image registries gathered by the
|
// Deprecated: v1beta1 is no longer supported, use v1 instead.
|
||||||
// image-reflector-controller. v1alpha2 did some rearrangement from
|
|
||||||
// v1alpha1 to make room for future enhancements; v1beta1 does not
|
|
||||||
// change the schema from v1alpha2.
|
|
||||||
//
|
//
|
||||||
// +kubebuilder:object:generate=true
|
// +kubebuilder:object:generate=true
|
||||||
// +groupName=image.toolkit.fluxcd.io
|
// +groupName=image.toolkit.fluxcd.io
|
||||||
|
|
|
@ -133,10 +133,8 @@ func SetImageUpdateAutomationReadiness(auto *ImageUpdateAutomation, status metav
|
||||||
apimeta.SetStatusCondition(auto.GetStatusConditions(), newCondition)
|
apimeta.SetStatusCondition(auto.GetStatusConditions(), newCondition)
|
||||||
}
|
}
|
||||||
|
|
||||||
//+kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
//+kubebuilder:subresource:status
|
// +kubebuilder:skipversion
|
||||||
//+kubebuilder:deprecatedversion:warning="v1beta1 ImageUpdateAutomation is deprecated, upgrade to v1beta2"
|
|
||||||
//+kubebuilder:printcolumn:name="Last run",type=string,JSONPath=`.status.lastAutomationRunTime`
|
|
||||||
|
|
||||||
// ImageUpdateAutomation is the Schema for the imageupdateautomations API
|
// ImageUpdateAutomation is the Schema for the imageupdateautomations API
|
||||||
type ImageUpdateAutomation struct {
|
type ImageUpdateAutomation struct {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//go:build !ignore_autogenerated
|
//go:build !ignore_autogenerated
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2024 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -36,4 +36,7 @@ const (
|
||||||
|
|
||||||
// InvalidPolicySelectorReason represents an invalid policy selector.
|
// InvalidPolicySelectorReason represents an invalid policy selector.
|
||||||
InvalidPolicySelectorReason string = "InvalidPolicySelector"
|
InvalidPolicySelectorReason string = "InvalidPolicySelector"
|
||||||
|
|
||||||
|
// RemovedTemplateFieldReason represents usage of removed template field.
|
||||||
|
RemovedTemplateFieldReason string = "RemovedTemplateField"
|
||||||
)
|
)
|
||||||
|
|
|
@ -65,6 +65,7 @@ type CommitSpec struct {
|
||||||
SigningKey *SigningKey `json:"signingKey,omitempty"`
|
SigningKey *SigningKey `json:"signingKey,omitempty"`
|
||||||
// MessageTemplate provides a template for the commit message,
|
// MessageTemplate provides a template for the commit message,
|
||||||
// into which will be interpolated the details of the change made.
|
// into which will be interpolated the details of the change made.
|
||||||
|
// Note: The `Updated` template field has been removed. Use `Changed` instead.
|
||||||
// +optional
|
// +optional
|
||||||
MessageTemplate string `json:"messageTemplate,omitempty"`
|
MessageTemplate string `json:"messageTemplate,omitempty"`
|
||||||
|
|
||||||
|
|
|
@ -83,9 +83,9 @@ const (
|
||||||
// inlined here.
|
// inlined here.
|
||||||
type UpdateStrategy struct {
|
type UpdateStrategy struct {
|
||||||
// Strategy names the strategy to be used.
|
// Strategy names the strategy to be used.
|
||||||
// +required
|
// +optional
|
||||||
// +kubebuilder:default=Setters
|
// +kubebuilder:default=Setters
|
||||||
Strategy UpdateStrategyName `json:"strategy"`
|
Strategy UpdateStrategyName `json:"strategy,omitempty"`
|
||||||
|
|
||||||
// Path to the directory containing the manifests to be updated.
|
// Path to the directory containing the manifests to be updated.
|
||||||
// Defaults to 'None', which translates to the root path
|
// Defaults to 'None', which translates to the root path
|
||||||
|
@ -132,7 +132,11 @@ type ObservedPolicies map[string]ImageRef
|
||||||
//+kubebuilder:storageversion
|
//+kubebuilder:storageversion
|
||||||
//+kubebuilder:object:root=true
|
//+kubebuilder:object:root=true
|
||||||
//+kubebuilder:subresource:status
|
//+kubebuilder:subresource:status
|
||||||
//+kubebuilder:printcolumn:name="Last run",type=string,JSONPath=`.status.lastAutomationRunTime`
|
//+kubebuilder:resource:shortName=iua;imgupd;imgauto
|
||||||
|
//+kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
||||||
|
//+kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
|
||||||
|
//+kubebuilder:printcolumn:name="Last run",type="string",JSONPath=".status.lastAutomationRunTime",priority=1
|
||||||
|
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
|
||||||
|
|
||||||
// ImageUpdateAutomation is the Schema for the imageupdateautomations API
|
// ImageUpdateAutomation is the Schema for the imageupdateautomations API
|
||||||
type ImageUpdateAutomation struct {
|
type ImageUpdateAutomation struct {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//go:build !ignore_autogenerated
|
//go:build !ignore_autogenerated
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2024 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.16.1
|
controller-gen.kubebuilder.io/version: v0.19.0
|
||||||
name: imageupdateautomations.image.toolkit.fluxcd.io
|
name: imageupdateautomations.image.toolkit.fluxcd.io
|
||||||
spec:
|
spec:
|
||||||
group: image.toolkit.fluxcd.io
|
group: image.toolkit.fluxcd.io
|
||||||
|
@ -11,326 +11,27 @@ spec:
|
||||||
kind: ImageUpdateAutomation
|
kind: ImageUpdateAutomation
|
||||||
listKind: ImageUpdateAutomationList
|
listKind: ImageUpdateAutomationList
|
||||||
plural: imageupdateautomations
|
plural: imageupdateautomations
|
||||||
|
shortNames:
|
||||||
|
- iua
|
||||||
|
- imgupd
|
||||||
|
- imgauto
|
||||||
singular: imageupdateautomation
|
singular: imageupdateautomation
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
versions:
|
versions:
|
||||||
- additionalPrinterColumns:
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||||
|
name: Ready
|
||||||
|
type: string
|
||||||
|
- jsonPath: .status.conditions[?(@.type=="Ready")].message
|
||||||
|
name: Status
|
||||||
|
type: string
|
||||||
- jsonPath: .status.lastAutomationRunTime
|
- jsonPath: .status.lastAutomationRunTime
|
||||||
name: Last run
|
name: Last run
|
||||||
|
priority: 1
|
||||||
type: string
|
type: string
|
||||||
deprecated: true
|
- jsonPath: .metadata.creationTimestamp
|
||||||
deprecationWarning: v1beta1 ImageUpdateAutomation is deprecated, upgrade to v1beta2
|
name: Age
|
||||||
name: v1beta1
|
type: date
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
description: ImageUpdateAutomation is the Schema for the imageupdateautomations
|
|
||||||
API
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: |-
|
|
||||||
APIVersion defines the versioned schema of this representation of an object.
|
|
||||||
Servers should convert recognized schemas to the latest internal value, and
|
|
||||||
may reject unrecognized values.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind is a string value representing the REST resource this object represents.
|
|
||||||
Servers may infer this from the endpoint the client submits requests to.
|
|
||||||
Cannot be updated.
|
|
||||||
In CamelCase.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
|
||||||
type: string
|
|
||||||
metadata:
|
|
||||||
type: object
|
|
||||||
spec:
|
|
||||||
description: ImageUpdateAutomationSpec defines the desired state of ImageUpdateAutomation
|
|
||||||
properties:
|
|
||||||
git:
|
|
||||||
description: |-
|
|
||||||
GitSpec contains all the git-specific definitions. This is
|
|
||||||
technically optional, but in practice mandatory until there are
|
|
||||||
other kinds of source allowed.
|
|
||||||
properties:
|
|
||||||
checkout:
|
|
||||||
description: |-
|
|
||||||
Checkout gives the parameters for cloning the git repository,
|
|
||||||
ready to make changes. If not present, the `spec.ref` field from the
|
|
||||||
referenced `GitRepository` or its default will be used.
|
|
||||||
properties:
|
|
||||||
ref:
|
|
||||||
description: |-
|
|
||||||
Reference gives a branch, tag or commit to clone from the Git
|
|
||||||
repository.
|
|
||||||
properties:
|
|
||||||
branch:
|
|
||||||
description: Branch to check out, defaults to 'master'
|
|
||||||
if no other field is defined.
|
|
||||||
type: string
|
|
||||||
commit:
|
|
||||||
description: |-
|
|
||||||
Commit SHA to check out, takes precedence over all reference fields.
|
|
||||||
|
|
||||||
This can be combined with Branch to shallow clone the branch, in which
|
|
||||||
the commit is expected to exist.
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: |-
|
|
||||||
Name of the reference to check out; takes precedence over Branch, Tag and SemVer.
|
|
||||||
|
|
||||||
It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description
|
|
||||||
Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head"
|
|
||||||
type: string
|
|
||||||
semver:
|
|
||||||
description: SemVer tag expression to check out, takes
|
|
||||||
precedence over Tag.
|
|
||||||
type: string
|
|
||||||
tag:
|
|
||||||
description: Tag to check out, takes precedence over Branch.
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- ref
|
|
||||||
type: object
|
|
||||||
commit:
|
|
||||||
description: Commit specifies how to commit to the git repository.
|
|
||||||
properties:
|
|
||||||
author:
|
|
||||||
description: |-
|
|
||||||
Author gives the email and optionally the name to use as the
|
|
||||||
author of commits.
|
|
||||||
properties:
|
|
||||||
email:
|
|
||||||
description: Email gives the email to provide when making
|
|
||||||
a commit.
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name gives the name to provide when making
|
|
||||||
a commit.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- email
|
|
||||||
type: object
|
|
||||||
messageTemplate:
|
|
||||||
description: |-
|
|
||||||
MessageTemplate provides a template for the commit message,
|
|
||||||
into which will be interpolated the details of the change made.
|
|
||||||
type: string
|
|
||||||
signingKey:
|
|
||||||
description: SigningKey provides the option to sign commits
|
|
||||||
with a GPG key
|
|
||||||
properties:
|
|
||||||
secretRef:
|
|
||||||
description: |-
|
|
||||||
SecretRef holds the name to a secret that contains a 'git.asc' key
|
|
||||||
corresponding to the ASCII Armored file containing the GPG signing
|
|
||||||
keypair as the value. It must be in the same namespace as the
|
|
||||||
ImageUpdateAutomation.
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
description: Name of the referent.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- secretRef
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- author
|
|
||||||
type: object
|
|
||||||
push:
|
|
||||||
description: |-
|
|
||||||
Push specifies how and where to push commits made by the
|
|
||||||
automation. If missing, commits are pushed (back) to
|
|
||||||
`.spec.checkout.branch` or its default.
|
|
||||||
properties:
|
|
||||||
branch:
|
|
||||||
description: |-
|
|
||||||
Branch specifies that commits should be pushed to the branch
|
|
||||||
named. The branch is created using `.spec.checkout.branch` as the
|
|
||||||
starting point, if it doesn't already exist.
|
|
||||||
type: string
|
|
||||||
options:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
Options specifies the push options that are sent to the Git
|
|
||||||
server when performing a push operation. For details, see:
|
|
||||||
https://git-scm.com/docs/git-push#Documentation/git-push.txt---push-optionltoptiongt
|
|
||||||
type: object
|
|
||||||
refspec:
|
|
||||||
description: |-
|
|
||||||
Refspec specifies the Git Refspec to use for a push operation.
|
|
||||||
If both Branch and Refspec are provided, then the commit is pushed
|
|
||||||
to the branch and also using the specified refspec.
|
|
||||||
For more details about Git Refspecs, see:
|
|
||||||
https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- commit
|
|
||||||
type: object
|
|
||||||
interval:
|
|
||||||
description: |-
|
|
||||||
Interval gives an lower bound for how often the automation
|
|
||||||
run should be attempted.
|
|
||||||
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
|
|
||||||
type: string
|
|
||||||
sourceRef:
|
|
||||||
description: |-
|
|
||||||
SourceRef refers to the resource giving access details
|
|
||||||
to a git repository.
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: API version of the referent.
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
default: GitRepository
|
|
||||||
description: Kind of the referent.
|
|
||||||
enum:
|
|
||||||
- GitRepository
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: Name of the referent.
|
|
||||||
type: string
|
|
||||||
namespace:
|
|
||||||
description: Namespace of the referent, defaults to the namespace
|
|
||||||
of the Kubernetes resource object that contains the reference.
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- kind
|
|
||||||
- name
|
|
||||||
type: object
|
|
||||||
suspend:
|
|
||||||
description: |-
|
|
||||||
Suspend tells the controller to not run this automation, until
|
|
||||||
it is unset (or set to false). Defaults to false.
|
|
||||||
type: boolean
|
|
||||||
update:
|
|
||||||
default:
|
|
||||||
strategy: Setters
|
|
||||||
description: |-
|
|
||||||
Update gives the specification for how to update the files in
|
|
||||||
the repository. This can be left empty, to use the default
|
|
||||||
value.
|
|
||||||
properties:
|
|
||||||
path:
|
|
||||||
description: |-
|
|
||||||
Path to the directory containing the manifests to be updated.
|
|
||||||
Defaults to 'None', which translates to the root path
|
|
||||||
of the GitRepositoryRef.
|
|
||||||
type: string
|
|
||||||
strategy:
|
|
||||||
default: Setters
|
|
||||||
description: Strategy names the strategy to be used.
|
|
||||||
enum:
|
|
||||||
- Setters
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- strategy
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- interval
|
|
||||||
- sourceRef
|
|
||||||
type: object
|
|
||||||
status:
|
|
||||||
default:
|
|
||||||
observedGeneration: -1
|
|
||||||
description: ImageUpdateAutomationStatus defines the observed state of
|
|
||||||
ImageUpdateAutomation
|
|
||||||
properties:
|
|
||||||
conditions:
|
|
||||||
items:
|
|
||||||
description: Condition contains details for one aspect of the current
|
|
||||||
state of this API Resource.
|
|
||||||
properties:
|
|
||||||
lastTransitionTime:
|
|
||||||
description: |-
|
|
||||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
|
||||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
|
||||||
format: date-time
|
|
||||||
type: string
|
|
||||||
message:
|
|
||||||
description: |-
|
|
||||||
message is a human readable message indicating details about the transition.
|
|
||||||
This may be an empty string.
|
|
||||||
maxLength: 32768
|
|
||||||
type: string
|
|
||||||
observedGeneration:
|
|
||||||
description: |-
|
|
||||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
|
||||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
|
||||||
with respect to the current state of the instance.
|
|
||||||
format: int64
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
|
||||||
reason:
|
|
||||||
description: |-
|
|
||||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
|
||||||
Producers of specific condition types may define expected values and meanings for this field,
|
|
||||||
and whether the values are considered a guaranteed API.
|
|
||||||
The value should be a CamelCase string.
|
|
||||||
This field may not be empty.
|
|
||||||
maxLength: 1024
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
|
||||||
type: string
|
|
||||||
status:
|
|
||||||
description: status of the condition, one of True, False, Unknown.
|
|
||||||
enum:
|
|
||||||
- "True"
|
|
||||||
- "False"
|
|
||||||
- Unknown
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
|
||||||
maxLength: 316
|
|
||||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- lastTransitionTime
|
|
||||||
- message
|
|
||||||
- reason
|
|
||||||
- status
|
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
lastAutomationRunTime:
|
|
||||||
description: |-
|
|
||||||
LastAutomationRunTime records the last time the controller ran
|
|
||||||
this automation through to completion (even if no updates were
|
|
||||||
made).
|
|
||||||
format: date-time
|
|
||||||
type: string
|
|
||||||
lastHandledReconcileAt:
|
|
||||||
description: |-
|
|
||||||
LastHandledReconcileAt holds the value of the most recent
|
|
||||||
reconcile request value, so a change of the annotation value
|
|
||||||
can be detected.
|
|
||||||
type: string
|
|
||||||
lastPushCommit:
|
|
||||||
description: |-
|
|
||||||
LastPushCommit records the SHA1 of the last commit made by the
|
|
||||||
controller, for this automation object
|
|
||||||
type: string
|
|
||||||
lastPushTime:
|
|
||||||
description: LastPushTime records the time of the last pushed change.
|
|
||||||
format: date-time
|
|
||||||
type: string
|
|
||||||
observedGeneration:
|
|
||||||
format: int64
|
|
||||||
type: integer
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
served: true
|
|
||||||
storage: false
|
|
||||||
subresources:
|
|
||||||
status: {}
|
|
||||||
- additionalPrinterColumns:
|
|
||||||
- jsonPath: .status.lastAutomationRunTime
|
|
||||||
name: Last run
|
|
||||||
type: string
|
|
||||||
name: v1beta2
|
name: v1beta2
|
||||||
schema:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
|
@ -426,6 +127,7 @@ spec:
|
||||||
description: |-
|
description: |-
|
||||||
MessageTemplate provides a template for the commit message,
|
MessageTemplate provides a template for the commit message,
|
||||||
into which will be interpolated the details of the change made.
|
into which will be interpolated the details of the change made.
|
||||||
|
Note: The `Updated` template field has been removed. Use `Changed` instead.
|
||||||
type: string
|
type: string
|
||||||
messageTemplateValues:
|
messageTemplateValues:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
|
@ -593,8 +295,6 @@ spec:
|
||||||
enum:
|
enum:
|
||||||
- Setters
|
- Setters
|
||||||
type: string
|
type: string
|
||||||
required:
|
|
||||||
- strategy
|
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- interval
|
- interval
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
apiVersion: image.toolkit.fluxcd.io/v1beta1
|
|
||||||
kind: ImageUpdateAutomation
|
|
||||||
metadata:
|
|
||||||
name: imageupdateautomation-sample
|
|
||||||
spec:
|
|
||||||
interval: 5m
|
|
||||||
sourceRef:
|
|
||||||
kind: GitRepository # the only valid value, but good practice to be explicit here
|
|
||||||
name: sample-repo
|
|
||||||
git:
|
|
||||||
checkout:
|
|
||||||
ref:
|
|
||||||
branch: main
|
|
||||||
commit:
|
|
||||||
author:
|
|
||||||
name: fluxbot
|
|
||||||
email: fluxbot@example.com
|
|
||||||
messageTemplate: |
|
|
||||||
An automated update from FluxBot
|
|
||||||
|
|
||||||
[ci skip]
|
|
||||||
signingKey:
|
|
||||||
secretRef:
|
|
||||||
name: git-pgp
|
|
||||||
push:
|
|
||||||
branch: auto
|
|
||||||
update:
|
|
||||||
strategy: Setters
|
|
||||||
path: ./cluster/sample
|
|
|
@ -67,7 +67,8 @@ string
|
||||||
<td>
|
<td>
|
||||||
<em>(Optional)</em>
|
<em>(Optional)</em>
|
||||||
<p>MessageTemplate provides a template for the commit message,
|
<p>MessageTemplate provides a template for the commit message,
|
||||||
into which will be interpolated the details of the change made.</p>
|
into which will be interpolated the details of the change made.
|
||||||
|
Note: The <code>Updated</code> template field has been removed. Use <code>Changed</code> instead.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -873,6 +874,7 @@ UpdateStrategyName
|
||||||
</em>
|
</em>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
<p>Strategy names the strategy to be used.</p>
|
<p>Strategy names the strategy to be used.</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -374,12 +374,12 @@ spec:
|
||||||
Automated image update by Flux
|
Automated image update by Flux
|
||||||
```
|
```
|
||||||
|
|
||||||
**Deprecation Note:** The `Updated` template data available in v1beta1 API is
|
**Removal Note:** The `Updated` template data has been removed from the API.
|
||||||
deprecated. `Changed` template data is recommended for template data, as it
|
Use `Changed` template data instead, as it accommodates for all the updates,
|
||||||
accommodates for all the updates, including partial updates to just the image
|
including partial updates to just the image name or the tag, not just full image
|
||||||
name or the tag, not just full image with name and tag update. The old templates
|
with name and tag update. Templates using `Updated` will result in an error and
|
||||||
will continue to work in v1beta2 API as `Updated` has not been removed yet. In
|
the ImageUpdateAutomation will be marked as Stalled.
|
||||||
the next API version, `Updated` may be removed.
|
|
||||||
|
|
||||||
The message template also has access to the data related to the changes made by
|
The message template also has access to the data related to the changes made by
|
||||||
the automation. The template is a [Go text template][go-text-template]. The data
|
the automation. The template is a [Go text template][go-text-template]. The data
|
||||||
|
@ -393,14 +393,14 @@ type TemplateData struct {
|
||||||
AutomationObject struct {
|
AutomationObject struct {
|
||||||
Name, Namespace string
|
Name, Namespace string
|
||||||
}
|
}
|
||||||
Changed update.ResultV2
|
Changed update.Result
|
||||||
Values map[string]string
|
Values map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResultV2 contains the file changes made during the update. It contains
|
// Result contains the file changes made during the update. It contains
|
||||||
// details about the exact changes made to the files and the objects in them. It
|
// details about the exact changes made to the files and the objects in them. It
|
||||||
// has a nested structure file->objects->changes.
|
// has a nested structure file->objects->changes.
|
||||||
type ResultV2 struct {
|
type Result struct {
|
||||||
FileChanges map[string]ObjectChanges
|
FileChanges map[string]ObjectChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,10 +427,10 @@ over the changed objects and changes:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Changes returns all the changes that were made in at least one update.
|
// Changes returns all the changes that were made in at least one update.
|
||||||
func (r ResultV2) Changes() []Change
|
func (r Result) Changes() []Change
|
||||||
|
|
||||||
// Objects returns ObjectChanges, regardless of which file they appear in.
|
// Objects returns ObjectChanges, regardless of which file they appear in.
|
||||||
func (r ResultV2) Objects() ObjectChanges
|
func (r Result) Objects() ObjectChanges
|
||||||
```
|
```
|
||||||
|
|
||||||
Example of using the methods in a template:
|
Example of using the methods in a template:
|
||||||
|
@ -558,7 +558,13 @@ destination reference. An example of a valid refspec is
|
||||||
If both `.push.refspec` and `.push.branch` are specified, then the reconciler
|
If both `.push.refspec` and `.push.branch` are specified, then the reconciler
|
||||||
will push to both the destinations. This is particularly useful for working with
|
will push to both the destinations. This is particularly useful for working with
|
||||||
Gerrit servers. For more information about this, please refer to the
|
Gerrit servers. For more information about this, please refer to the
|
||||||
[Gerrit](#gerrit) section.
|
[Gerrit](#gerrit) section. This can also be used to automatically open
|
||||||
|
Pull-Requests in Gitea or Forgejo. See the [Gitea](#gitea) section for
|
||||||
|
an example.
|
||||||
|
|
||||||
|
If only `.push.refspec` is set, without explicitly defining a `.push.branch`, the
|
||||||
|
controller falls back to pushing to the branch from `checkoutRef` and *also*
|
||||||
|
pushes to `.push.refspec`.
|
||||||
|
|
||||||
**Note:** If both `.push.refspec` and `.push.branch` are essentially equal to
|
**Note:** If both `.push.refspec` and `.push.branch` are essentially equal to
|
||||||
each other (for e.g.: `.push.refspec: refs/heads/main:refs/heads/main` and
|
each other (for e.g.: `.push.refspec: refs/heads/main:refs/heads/main` and
|
||||||
|
@ -958,6 +964,42 @@ image tag to a different one, it leads to a distinct Change-Id for the commit.
|
||||||
Consequently, this action will trigger the creation of an additional Change,
|
Consequently, this action will trigger the creation of an additional Change,
|
||||||
even when an existing Change containing outdated modifications remains open.
|
even when an existing Change containing outdated modifications remains open.
|
||||||
|
|
||||||
|
#### Gitea
|
||||||
|
|
||||||
|
[Gitea](https://docs.gitea.com/usage/agit) and [Forgejo](https://forgejo.org/docs/latest/user/agit-support/) each implement the AGit-Workflow.
|
||||||
|
This means, the image-automation-controller is able to open a pull-request by
|
||||||
|
pushing to a `refspec` like `HEAD:refs/for/main` with the apropriate [push-options](#push-options).
|
||||||
|
|
||||||
|
The following example opens a PR on a Gitea or Forgejo-Server:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: image.toolkit.fluxcd.io/v1beta2
|
||||||
|
kind: ImageUpdateAutomation
|
||||||
|
metadata:
|
||||||
|
name: my-automation
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
git:
|
||||||
|
checkout:
|
||||||
|
ref:
|
||||||
|
branch: main
|
||||||
|
push:
|
||||||
|
branch: flux-updates
|
||||||
|
refspec: refs/heads/flux-updates:refs/for/main
|
||||||
|
options:
|
||||||
|
topic: flux-updates
|
||||||
|
title: Flux Image Update
|
||||||
|
description: |-
|
||||||
|
This PR is automatically opened by the fluxcd *image-automation-controller*
|
||||||
|
commit:
|
||||||
|
author:
|
||||||
|
email: flux@eaample.com
|
||||||
|
name: fluxcd
|
||||||
|
messageTemplate: '{{range .Changed.Changes}}{{print .OldValue}} -> {{println
|
||||||
|
.NewValue}}{{end}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## ImageUpdateAutomation Status
|
## ImageUpdateAutomation Status
|
||||||
|
|
||||||
### Observed Policies
|
### Observed Policies
|
||||||
|
|
178
go.mod
178
go.mod
|
@ -1,96 +1,103 @@
|
||||||
module github.com/fluxcd/image-automation-controller
|
module github.com/fluxcd/image-automation-controller
|
||||||
|
|
||||||
go 1.24.0
|
go 1.25.0
|
||||||
|
|
||||||
replace github.com/fluxcd/image-automation-controller/api => ./api
|
replace github.com/fluxcd/image-automation-controller/api => ./api
|
||||||
|
|
||||||
// Pin kustomize to v5.6.0
|
// Pin kustomize to v5.7.1
|
||||||
replace (
|
replace (
|
||||||
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.19.0
|
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.20.1
|
||||||
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.19.0
|
sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.20.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
|
||||||
github.com/Masterminds/sprig/v3 v3.3.0
|
github.com/Masterminds/sprig/v3 v3.3.0
|
||||||
github.com/ProtonMail/go-crypto v1.2.0
|
github.com/ProtonMail/go-crypto v1.3.0
|
||||||
github.com/cyphar/filepath-securejoin v0.4.1
|
github.com/cyphar/filepath-securejoin v0.4.1
|
||||||
github.com/fluxcd/image-automation-controller/api v0.41.2
|
github.com/fluxcd/image-automation-controller/api v0.41.2
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.35.2
|
github.com/fluxcd/image-reflector-controller/api v0.35.2
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0
|
github.com/fluxcd/pkg/apis/acl v0.9.0
|
||||||
github.com/fluxcd/pkg/apis/event v0.17.0
|
github.com/fluxcd/pkg/apis/event v0.19.0
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0
|
github.com/fluxcd/pkg/apis/meta v1.20.0
|
||||||
github.com/fluxcd/pkg/auth v0.17.0
|
github.com/fluxcd/pkg/auth v0.29.0
|
||||||
github.com/fluxcd/pkg/cache v0.9.0
|
github.com/fluxcd/pkg/cache v0.11.0
|
||||||
github.com/fluxcd/pkg/git v0.32.0
|
github.com/fluxcd/pkg/git v0.36.0
|
||||||
github.com/fluxcd/pkg/git/gogit v0.35.1
|
github.com/fluxcd/pkg/git/gogit v0.40.0
|
||||||
github.com/fluxcd/pkg/gittestserver v0.17.0
|
github.com/fluxcd/pkg/gittestserver v0.20.0
|
||||||
github.com/fluxcd/pkg/runtime v0.60.0
|
github.com/fluxcd/pkg/runtime v0.82.0
|
||||||
github.com/fluxcd/pkg/ssh v0.19.0
|
github.com/fluxcd/pkg/ssh v0.21.0
|
||||||
github.com/fluxcd/source-controller/api v1.6.1
|
github.com/fluxcd/source-controller/api v1.6.2
|
||||||
github.com/go-git/go-billy/v5 v5.6.2
|
github.com/go-git/go-billy/v5 v5.6.2
|
||||||
github.com/go-git/go-git/v5 v5.16.2
|
github.com/go-git/go-git/v5 v5.16.2
|
||||||
github.com/go-logr/logr v1.4.2
|
github.com/go-logr/logr v1.4.3
|
||||||
github.com/google/go-containerregistry v0.20.3
|
github.com/google/go-containerregistry v0.20.6
|
||||||
github.com/onsi/gomega v1.37.0
|
github.com/onsi/gomega v1.38.2
|
||||||
github.com/otiai10/copy v1.14.1
|
github.com/otiai10/copy v1.14.1
|
||||||
github.com/spf13/pflag v1.0.6
|
github.com/spf13/pflag v1.0.7
|
||||||
k8s.io/api v0.33.0
|
k8s.io/api v0.34.0
|
||||||
k8s.io/apimachinery v0.33.0
|
k8s.io/apimachinery v0.34.0
|
||||||
k8s.io/client-go v0.33.0
|
k8s.io/client-go v0.34.0
|
||||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff
|
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e
|
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
|
||||||
sigs.k8s.io/controller-runtime v0.21.0
|
sigs.k8s.io/controller-runtime v0.22.0
|
||||||
sigs.k8s.io/kustomize/kyaml v0.19.0
|
sigs.k8s.io/kustomize/kyaml v0.20.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
cloud.google.com/go/auth v0.16.5 // indirect
|
||||||
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
|
cloud.google.com/go/compute/metadata v0.8.0 // indirect
|
||||||
dario.cat/mergo v1.0.1 // indirect
|
dario.cat/mergo v1.0.1 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
|
github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 // indirect
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
||||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect
|
github.com/aws/aws-sdk-go-v2 v1.38.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect
|
github.com/aws/aws-sdk-go-v2/config v1.31.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect
|
github.com/aws/aws-sdk-go-v2/credentials v1.18.10 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ecr v1.50.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.0 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/eks v1.73.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 // indirect
|
||||||
github.com/aws/smithy-go v1.22.2 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 // indirect
|
||||||
|
github.com/aws/smithy-go v1.23.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||||
github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 // indirect
|
github.com/bradleyfalzon/ghinstallation/v2 v2.16.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/chai2010/gettext-go v1.0.3 // indirect
|
github.com/chai2010/gettext-go v1.0.3 // indirect
|
||||||
github.com/cloudflare/circl v1.6.1 // indirect
|
github.com/cloudflare/circl v1.6.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/docker/cli v27.5.0+incompatible // indirect
|
github.com/docker/cli v28.2.2+incompatible // indirect
|
||||||
github.com/docker/docker-credential-helpers v0.8.2 // indirect
|
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
||||||
github.com/emirpasic/gods v1.18.1 // indirect
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.13 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
|
github.com/fluxcd/cli-utils v0.36.0-flux.15 // indirect
|
||||||
github.com/fluxcd/gitkit v0.6.0 // indirect
|
github.com/fluxcd/gitkit v0.6.0 // indirect
|
||||||
github.com/fluxcd/pkg/version v0.7.0 // indirect
|
github.com/fluxcd/pkg/version v0.10.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||||
github.com/go-errors/errors v1.5.1 // indirect
|
github.com/go-errors/errors v1.5.1 // indirect
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-logr/zapr v1.3.0 // indirect
|
github.com/go-logr/zapr v1.3.0 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||||
|
@ -98,19 +105,21 @@ require (
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||||
github.com/google/btree v1.1.3 // indirect
|
github.com/google/btree v1.1.3 // indirect
|
||||||
github.com/google/gnostic-models v0.6.9 // indirect
|
github.com/google/gnostic-models v0.7.0 // indirect
|
||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/google/go-github/v71 v71.0.0 // indirect
|
github.com/google/go-github/v72 v72.0.0 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||||
|
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||||
github.com/huandu/xstrings v1.5.0 // indirect
|
github.com/huandu/xstrings v1.5.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
|
@ -127,20 +136,21 @@ require (
|
||||||
github.com/moby/spdystream v0.5.0 // indirect
|
github.com/moby/spdystream v0.5.0 // indirect
|
||||||
github.com/moby/term v0.5.2 // indirect
|
github.com/moby/term v0.5.2 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/otiai10/mint v1.6.3 // indirect
|
github.com/otiai10/mint v1.6.3 // indirect
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
github.com/pjbgf/sha1cd v0.4.0 // indirect
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/prometheus/client_golang v1.22.0 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.23.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
github.com/prometheus/client_model v0.6.2 // indirect
|
||||||
github.com/prometheus/common v0.63.0 // indirect
|
github.com/prometheus/common v0.65.0 // indirect
|
||||||
github.com/prometheus/procfs v0.16.1 // indirect
|
github.com/prometheus/procfs v0.17.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||||
github.com/shopspring/decimal v1.4.0 // indirect
|
github.com/shopspring/decimal v1.4.0 // indirect
|
||||||
|
@ -151,30 +161,40 @@ require (
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
github.com/xlab/treeprint v1.2.0 // indirect
|
github.com/xlab/treeprint v1.2.0 // indirect
|
||||||
|
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/crypto v0.39.0 // indirect
|
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||||
golang.org/x/net v0.40.0 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/oauth2 v0.29.0 // indirect
|
golang.org/x/crypto v0.41.0 // indirect
|
||||||
golang.org/x/sync v0.15.0 // indirect
|
golang.org/x/net v0.43.0 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/oauth2 v0.30.0 // indirect
|
||||||
golang.org/x/term v0.32.0 // indirect
|
golang.org/x/sync v0.16.0 // indirect
|
||||||
golang.org/x/text v0.26.0 // indirect
|
golang.org/x/sys v0.35.0 // indirect
|
||||||
golang.org/x/time v0.11.0 // indirect
|
golang.org/x/term v0.34.0 // indirect
|
||||||
|
golang.org/x/text v0.28.0 // indirect
|
||||||
|
golang.org/x/time v0.12.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/api v0.248.0 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect
|
||||||
|
google.golang.org/grpc v1.74.2 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.7 // indirect
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/apiextensions-apiserver v0.33.0 // indirect
|
k8s.io/apiextensions-apiserver v0.34.0 // indirect
|
||||||
k8s.io/cli-runtime v0.33.0 // indirect
|
k8s.io/cli-runtime v0.34.0 // indirect
|
||||||
k8s.io/component-base v0.33.0 // indirect
|
k8s.io/component-base v0.34.0 // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/kubectl v0.33.0 // indirect
|
k8s.io/kubectl v0.34.0 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||||
sigs.k8s.io/kustomize/api v0.19.0 // indirect
|
sigs.k8s.io/kustomize/api v0.20.1 // indirect
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
||||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
373
go.sum
373
go.sum
|
@ -1,17 +1,25 @@
|
||||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
|
||||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
|
||||||
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
|
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||||
|
cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA=
|
||||||
|
cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw=
|
||||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 h1:ci6Yd6nysBRLEodoziB6ah1+YOzZbZk+NYneoA6q+6E=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0/go.mod h1:QyVsSSN64v5TGltphKLQ2sQxe4OBQg0J1eKRcVBnfgE=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0 h1:MhRfI58HblXzCtWEZCO0feHs8LweePB3s90r7WaR1KU=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0/go.mod h1:kUjrAo8bgEwLeZ/CmHqNl3Z/kPm7y6FKfxxK0izYUg4=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0/go.mod h1:okZ+ZURbArNdlJ+ptXoyHNuOETzOl1Oww19rm8I2WLA=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
|
github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3 h1:ldKsKtEIblsgsr6mPwrd9yRntoX6uLz/K89wsldwx/k=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
|
github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3/go.mod h1:MAm7bk0oDLmD8yIkvfbxPW04fxzphPyL+7GzwHxOp6Y=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 h1:figxyQZXzZQIcP3njhC68bYUiTw45J8/SsHaLW8Ax0M=
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0/go.mod h1:TmlMW4W5OvXOmOyKNnor8nlMMiO1ctIyzmHme/VHsrA=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
|
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
|
||||||
|
@ -22,63 +30,65 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ
|
||||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||||
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
|
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
|
||||||
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
|
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
|
||||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
|
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||||
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
|
github.com/aws/aws-sdk-go-v2 v1.38.3 h1:B6cV4oxnMs45fql4yRH+/Po/YU+597zgWqvDpYMturk=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
|
github.com/aws/aws-sdk-go-v2 v1.38.3/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM=
|
github.com/aws/aws-sdk-go-v2/config v1.31.6 h1:a1t8fXY4GT4xjyJExz4knbuoxSCacB5hT/WgtfPyLjo=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g=
|
github.com/aws/aws-sdk-go-v2/config v1.31.6/go.mod h1:5ByscNi7R+ztvOGzeUaIu49vkMk2soq5NaH5PYe33MQ=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=
|
github.com/aws/aws-sdk-go-v2/credentials v1.18.10 h1:xdJnXCouCx8Y0NncgoptztUocIYLKeQxrCgN6x9sdhg=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=
|
github.com/aws/aws-sdk-go-v2/credentials v1.18.10/go.mod h1:7tQk08ntj914F/5i9jC4+2HQTAuJirq7m1vZVIhEkWs=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6 h1:wbjnrrMnKew78/juW7I2BtKQwa1qlf6EjQgS69uYY14=
|
||||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.6/go.mod h1:AtiqqNrDioJXuUgz3+3T0mBWN7Hro2n9wll2zRUc0ww=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 h1:uF68eJA6+S9iVr9WgX1NaRGyQ/6MdIyc4JNUo6TN1FA=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6/go.mod h1:qlPeVZCGPiobx8wb1ft0GHT5l+dc6ldnwInDFaMvC7Y=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 h1:pa1DEC6JoI0zduhZePp3zmhWvk/xxm4NB8Hy/Tlsgos=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6/go.mod h1:gxEjPebnhWGJoaDdtDkA0JX46VRg1wcTHYe63OfX5pE=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
|
||||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 h1:YyH8Hk73bYzdbvf6S8NF5z/fb/1stpiMnFSfL6jSfRA=
|
github.com/aws/aws-sdk-go-v2/service/ecr v1.50.1 h1:lcwFjRx3C/hBxJzoWkD6DIG2jeB+mzLmFVBFVOadxxE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3/go.mod h1:iQ1skgw1XRK+6Lgkb0I9ODatAP72WoTILh0zXQ5DtbU=
|
github.com/aws/aws-sdk-go-v2/service/ecr v1.50.1/go.mod h1:qt9OL5kXqWoSub4QAkOF74mS3M2zOTNxMODqgwEUjt8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.0 h1:wA2O6pZ2r5smqJunFP4hp7qptMW4EQxs8O6RVHPulOE=
|
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2 h1:EfatDVSMFxaS5TiR0C0zssQU1Nm+rGx3VbUGIH1y274=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.0/go.mod h1:RZL7ov7c72wSmoM8bIiVxRHgcVdzhNkVW2J36C8RF4s=
|
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.37.2/go.mod h1:oRy1IEgzXtOkEk4B/J7HZbXUC258drDLtkmc++lN7IA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
|
github.com/aws/aws-sdk-go-v2/service/eks v1.73.1 h1:Txq5jxY/ao+2Vx/kX9+65WTqkzCnxSlXnwIj+Cr/fng=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
|
github.com/aws/aws-sdk-go-v2/service/eks v1.73.1/go.mod h1:+hYFg3laewH0YCfJRv+o5R3bradDKmFIm/uaiaD1U7U=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM=
|
||||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6 h1:LHS1YAIJXJ4K9zS+1d/xa9JAA9sL2QyXIQCQFQW/X08=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.6/go.mod h1:c9PCiTEuh0wQID5/KqA32J+HAgZxN9tOGXKCiYJjTZI=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.29.1 h1:8OLZnVJPvjnrxEwHFg9hVUof/P4sibH+Ea4KKuqAGSg=
|
||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
|
github.com/aws/aws-sdk-go-v2/service/sso v1.29.1/go.mod h1:27M3BpVi0C02UiQh1w9nsBEit6pLhlaH3NHna6WUbDE=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2 h1:gKWSTnqudpo8dAxqBqZnDoDWCiEh/40FziUjr/mo6uA=
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.34.2/go.mod h1:x7+rkNmRoEN1U13A6JE2fXne9EWyJy54o3n6d4mGaXQ=
|
||||||
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.38.2 h1:YZPjhyaGzhDQEvsffDEcpycq49nl7fiGcfJTIo8BszI=
|
||||||
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
github.com/aws/aws-sdk-go-v2/service/sts v1.38.2/go.mod h1:2dIN8qhQfv37BdUYGgEC8Q3tteM3zFxTI1MLO2O3J3c=
|
||||||
|
github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
|
||||||
|
github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||||
github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 h1:7r2rPUM04rgszMP0U1UZ1M5VoVVIlsaBSnpABfYxcQY=
|
github.com/bradleyfalzon/ghinstallation/v2 v2.16.0 h1:B91r9bHtXp/+XRgS5aZm6ZzTdz3ahgJYmkt4xZkgDz8=
|
||||||
github.com/bradleyfalzon/ghinstallation/v2 v2.15.0/go.mod h1:PoH9Vhy82OeRFZfxsVrk3mfQhVkEzou9OOwPOsEhiXE=
|
github.com/bradleyfalzon/ghinstallation/v2 v2.16.0/go.mod h1:OeVe5ggFzoBnmgitZe/A+BqGOnv1DvU/0uiLQi1wutM=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80=
|
github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80=
|
||||||
github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
|
||||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
|
github.com/coreos/go-oidc/v3 v3.15.0 h1:R6Oz8Z4bqWR7VFQ+sPSvZPQv4x8M+sJkDO5ojgwlyAg=
|
||||||
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
github.com/coreos/go-oidc/v3 v3.15.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||||
|
@ -88,12 +98,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/cli v27.5.0+incompatible h1:aMphQkcGtpHixwwhAXJT1rrK/detk2JIvDaFkLctbGM=
|
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||||
github.com/docker/cli v27.5.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
|
||||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
|
||||||
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||||
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
|
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
|
||||||
|
@ -108,42 +116,44 @@ github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
|
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
|
||||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.13 h1:2X5yjz/rk9mg7+bMFBDZKGKzeZpAmY2s6iwbNZz7OzM=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
github.com/fluxcd/cli-utils v0.36.0-flux.13/go.mod h1:b2iSoIeDTtjfCB0IKtGgqlhhvWa1oux3e90CjOf81oA=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
|
github.com/fluxcd/cli-utils v0.36.0-flux.15 h1:Et5QLnIpRjj+oZtM9gEybkAaoNsjysHq0y1253Ai94Y=
|
||||||
|
github.com/fluxcd/cli-utils v0.36.0-flux.15/go.mod h1:AqRUmWIfNE7cdL6NWSGF0bAlypGs+9x5UQ2qOtlEzv4=
|
||||||
github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg=
|
github.com/fluxcd/gitkit v0.6.0 h1:iNg5LTx6ePo+Pl0ZwqHTAkhbUHxGVSY3YCxCdw7VIFg=
|
||||||
github.com/fluxcd/gitkit v0.6.0/go.mod h1:svOHuKi0fO9HoawdK4HfHAJJseZDHHjk7I3ihnCIqNo=
|
github.com/fluxcd/gitkit v0.6.0/go.mod h1:svOHuKi0fO9HoawdK4HfHAJJseZDHHjk7I3ihnCIqNo=
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.35.2 h1:EzjtUpyx8kbTFx7ugdi5LRMaCpQW4kX/vjFCIPpPD38=
|
github.com/fluxcd/image-reflector-controller/api v0.35.2 h1:EzjtUpyx8kbTFx7ugdi5LRMaCpQW4kX/vjFCIPpPD38=
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.35.2/go.mod h1:mjpokoQhFs2RxfFjY4rHpn3ZAUvee8TiELyROFN4wiA=
|
github.com/fluxcd/image-reflector-controller/api v0.35.2/go.mod h1:mjpokoQhFs2RxfFjY4rHpn3ZAUvee8TiELyROFN4wiA=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0=
|
github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA=
|
||||||
github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ=
|
github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4=
|
||||||
github.com/fluxcd/pkg/apis/event v0.17.0 h1:foEINE++pCJlWVhWjYDXfkVmGKu8mQ4BDBlbYi5NU7M=
|
github.com/fluxcd/pkg/apis/event v0.19.0 h1:ZJU2voontkzp5rNYA4JMOu40S4tRcrWi4Do59EnyFwg=
|
||||||
github.com/fluxcd/pkg/apis/event v0.17.0/go.mod h1:0fLhLFiHlRTDKPDXdRnv+tS7mCMIQ0fJxnEfmvGM/5A=
|
github.com/fluxcd/pkg/apis/event v0.19.0/go.mod h1:deuIyUb6lh+Z1Ccvwwxhm1wNM3kpSo+vF1IgRnpaZfQ=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg=
|
github.com/fluxcd/pkg/apis/meta v1.20.0 h1:l9h0kWoDZTcYV0WJkFMgDXq6Q4tSojrJ+bHpFJSsaW0=
|
||||||
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
|
github.com/fluxcd/pkg/apis/meta v1.20.0/go.mod h1:XUAEUgT4gkWDAEN79E141tmL+v4SV50tVZ/Ojpc/ueg=
|
||||||
github.com/fluxcd/pkg/auth v0.17.0 h1:jgum55f5K7Db6yI2bi4WeKojTzQS9KxlHCC0CsFs5x8=
|
github.com/fluxcd/pkg/auth v0.29.0 h1:lLc63zjodqIqg5ydlU/Kp3Qa+wvh6G2khjop5MHALvk=
|
||||||
github.com/fluxcd/pkg/auth v0.17.0/go.mod h1:4h6s8VBNuec3tWd4xIReLw8BYPOKaIegjNMEbA4ikTU=
|
github.com/fluxcd/pkg/auth v0.29.0/go.mod h1:bjZ+6RMSGgsQQK+aPfVP8HWuBbb+FLlFxMiqd8ywzik=
|
||||||
github.com/fluxcd/pkg/cache v0.9.0 h1:EGKfOLMG3fOwWnH/4Axl5xd425mxoQbZzlZoLfd8PDk=
|
github.com/fluxcd/pkg/cache v0.11.0 h1:fsE8S+una21fSNw4MDXGUIf0Gf1J+pqa4RbsVKf2aTI=
|
||||||
github.com/fluxcd/pkg/cache v0.9.0/go.mod h1:jMwabjWfsC5lW8hE7NM3wtGNwSJ38Javx6EKbEi7INU=
|
github.com/fluxcd/pkg/cache v0.11.0/go.mod h1:2RTIU6PsJniHmfnllQWFEo7fa5V8KQlnMgn4o0sme40=
|
||||||
github.com/fluxcd/pkg/git v0.32.0 h1:agSE4Ia8saj5eg075qhLhZvjuTg/Hnj8mZU0meGKOyc=
|
github.com/fluxcd/pkg/git v0.36.0 h1:oakFKxTX5yiLcFzCS1SaV+mMXaODaF1Ic6/oCLfIe7I=
|
||||||
github.com/fluxcd/pkg/git v0.32.0/go.mod h1:rUgLXVQGBkBggHOLVMhHMHaweQ8Oc6HwZiN2Zm08Zxs=
|
github.com/fluxcd/pkg/git v0.36.0/go.mod h1:4TgfjcoM3B2sGsO5VbfBSwJQYzNCONGihcTOW8P3Jxw=
|
||||||
github.com/fluxcd/pkg/git/gogit v0.35.1 h1:NZI7rWDUUaGhEqgbvlh2CK9UZU/eteQ3eDTEMvdHmBo=
|
github.com/fluxcd/pkg/git/gogit v0.40.0 h1:VCsHC1440jMk1wAGWCwkgU2nDUBOPeYbCk6/OtvbY7Y=
|
||||||
github.com/fluxcd/pkg/git/gogit v0.35.1/go.mod h1:/WcAqTDBrjF+6cwFTaK7kNM791j/pXmw0fy8xbd1YWo=
|
github.com/fluxcd/pkg/git/gogit v0.40.0/go.mod h1:nQVyfa+rYSeVQiwVH5f/C4o1sf2MtMFjMlt3VSkC+P0=
|
||||||
github.com/fluxcd/pkg/gittestserver v0.17.0 h1:JlBvWZQTDOI+np5Z+084m3DkeAH1hMusEybyRUDF63k=
|
github.com/fluxcd/pkg/gittestserver v0.20.0 h1:xhzLV89mta23ZvTK0cpDCR6ni6vp5Di+9b4v3YBziMQ=
|
||||||
github.com/fluxcd/pkg/gittestserver v0.17.0/go.mod h1:E/40EmLoXcMqd6gLuLDC9F6KJxqHVGbBBeMNKk5XdxU=
|
github.com/fluxcd/pkg/gittestserver v0.20.0/go.mod h1:vGmM9eDJk56gx+osTcSHeScefnAaL4czR+rsNsvh0nw=
|
||||||
github.com/fluxcd/pkg/runtime v0.60.0 h1:d++EkV3FlycB+bzakB5NumwY4J8xts8i7lbvD6jBLeU=
|
github.com/fluxcd/pkg/runtime v0.82.0 h1:VdPPRJtj8/rcBdqY7GZSffoxe5elFHt+ymwQHNbPOlc=
|
||||||
github.com/fluxcd/pkg/runtime v0.60.0/go.mod h1:UeU0/eZLErYC/1bTmgzBfNXhiHy9fuQzjfLK0HxRgxY=
|
github.com/fluxcd/pkg/runtime v0.82.0/go.mod h1:rIDynMhU5upbn8ce3bXQhH5L6vtDw5MELycvtJG/+og=
|
||||||
github.com/fluxcd/pkg/ssh v0.19.0 h1:njSwNJQZ+3TGhBXshU/2TbqvooMbf6lQzFn7w6vuaKI=
|
github.com/fluxcd/pkg/ssh v0.21.0 h1:ZmyF0n9je0cTTkOpvFVgIhmdx9qtswnVE60TK4IzJh0=
|
||||||
github.com/fluxcd/pkg/ssh v0.19.0/go.mod h1:0e7sqpyekj65A4y/UUCVUxxVw8HonwFtJJ2KhvJQq1o=
|
github.com/fluxcd/pkg/ssh v0.21.0/go.mod h1:nX+gvJOmjf0E7lxq5mKKzDIdPEL2jOUQZbkBMS+mDtk=
|
||||||
github.com/fluxcd/pkg/version v0.7.0 h1:jZT5I6WFy1KlM40nHCSqlHmjC1VT1/DfmbAdOkIVVJc=
|
github.com/fluxcd/pkg/version v0.10.0 h1:WETlCRbfbocsDItkCCeh/4x4zQkZ5i/lUe7P7VaQBrI=
|
||||||
github.com/fluxcd/pkg/version v0.7.0/go.mod h1:3BjQDJXIZJmeJLXnfa2yG/sNAT1t5oeLAPfnSjOHNuA=
|
github.com/fluxcd/pkg/version v0.10.0/go.mod h1:dgmjEq4ykvBnqK1oVXM+hcXx3kAY/b4uZDYUn8XnHjk=
|
||||||
github.com/fluxcd/source-controller/api v1.6.1 h1:ZPTA9lNzBYHmwHfFX978qb8xVkdnQZHF1ggo6BoFm4w=
|
github.com/fluxcd/source-controller/api v1.6.2 h1:UmodAeqLIeF29HdTqf2GiacZyO+hJydJlepDaYsMvhc=
|
||||||
github.com/fluxcd/source-controller/api v1.6.1/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
|
github.com/fluxcd/source-controller/api v1.6.2/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw=
|
||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
|
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||||
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||||
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
|
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
|
||||||
|
@ -158,8 +168,11 @@ github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77
|
||||||
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
|
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||||
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
|
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
|
||||||
|
@ -176,33 +189,38 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||||
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||||
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
|
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||||
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
|
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI=
|
github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
|
||||||
github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI=
|
github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
|
||||||
github.com/google/go-github/v71 v71.0.0 h1:Zi16OymGKZZMm8ZliffVVJ/Q9YZreDKONCr+WUd0Z30=
|
github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM=
|
||||||
github.com/google/go-github/v71 v71.0.0/go.mod h1:URZXObp2BLlMjwu0O8g4y6VBneUj2bCHgnI8FfgZ51M=
|
github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
|
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ=
|
||||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
||||||
|
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||||
|
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
||||||
|
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
|
||||||
|
@ -211,8 +229,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=
|
||||||
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
||||||
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
@ -263,18 +281,19 @@ github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFL
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||||
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
github.com/onsi/ginkgo/v2 v2.25.2 h1:hepmgwx1D+llZleKQDMEvy8vIlCxMGt7W5ZxDjIEhsw=
|
||||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
github.com/onsi/ginkgo/v2 v2.25.2/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
|
||||||
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
|
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||||
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||||
|
@ -283,8 +302,8 @@ github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||||
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY=
|
||||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
@ -292,16 +311,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
||||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
||||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||||
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
|
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
||||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
||||||
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
|
|
||||||
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
|
|
||||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
@ -319,8 +336,9 @@ github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk=
|
||||||
github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||||
|
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
@ -329,8 +347,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
|
@ -339,6 +357,20 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
|
||||||
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||||
|
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||||
|
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||||
|
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||||
|
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||||
|
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
|
||||||
|
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||||
|
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
@ -347,12 +379,16 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||||
|
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
@ -360,15 +396,15 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||||
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
|
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||||
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -380,32 +416,42 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||||
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
|
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
google.golang.org/api v0.248.0 h1:hUotakSkcwGdYUqzCRc5yGYsg4wXxpkKlW5ryVqvC1Y=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
google.golang.org/api v0.248.0/go.mod h1:yAFUAF56Li7IuIQbTFoLwXTCI6XCFKueOlS7S9e4F9k=
|
||||||
|
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
|
||||||
|
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
|
||||||
|
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
|
||||||
|
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
|
||||||
|
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
|
||||||
|
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
@ -423,38 +469,37 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||||
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
|
k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE=
|
||||||
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
|
k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
|
||||||
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs=
|
k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc=
|
||||||
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc=
|
k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0=
|
||||||
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
|
k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0=
|
||||||
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||||
k8s.io/cli-runtime v0.33.0 h1:Lbl/pq/1o8BaIuyn+aVLdEPHVN665tBAXUePs8wjX7c=
|
k8s.io/cli-runtime v0.34.0 h1:N2/rUlJg6TMEBgtQ3SDRJwa8XyKUizwjlOknT1mB2Cw=
|
||||||
k8s.io/cli-runtime v0.33.0/go.mod h1:QcA+r43HeUM9jXFJx7A+yiTPfCooau/iCcP1wQh4NFw=
|
k8s.io/cli-runtime v0.34.0/go.mod h1:t/skRecS73Piv+J+FmWIQA2N2/rDjdYSQzEE67LUUs8=
|
||||||
k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98=
|
k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo=
|
||||||
k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg=
|
k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY=
|
||||||
k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk=
|
k8s.io/component-base v0.34.0 h1:bS8Ua3zlJzapklsB1dZgjEJuJEeHjj8yTu1gxE2zQX8=
|
||||||
k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU=
|
k8s.io/component-base v0.34.0/go.mod h1:RSCqUdvIjjrEm81epPcjQ/DS+49fADvGSCkIP3IC6vg=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
|
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
|
||||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
|
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
|
||||||
k8s.io/kubectl v0.33.0 h1:HiRb1yqibBSCqic4pRZP+viiOBAnIdwYDpzUFejs07g=
|
k8s.io/kubectl v0.34.0 h1:NcXz4TPTaUwhiX4LU+6r6udrlm0NsVnSkP3R9t0dmxs=
|
||||||
k8s.io/kubectl v0.33.0/go.mod h1:gAlGBuS1Jq1fYZ9AjGWbI/5Vk3M/VW2DK4g10Fpyn/0=
|
k8s.io/kubectl v0.34.0/go.mod h1:bmd0W5i+HuG7/p5sqicr0Li0rR2iIhXL0oUyLF3OjR4=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
|
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
|
sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0=
|
||||||
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
|
sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||||
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
|
sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I=
|
||||||
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o=
|
sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA=
|
sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY=
|
sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po=
|
||||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2024 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -58,7 +58,7 @@ import (
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
|
|
||||||
image_automationv1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
image_automationv1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/image-automation-controller/pkg/update"
|
"github.com/fluxcd/image-automation-controller/internal/update"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -39,7 +39,7 @@ import (
|
||||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
aclapi "github.com/fluxcd/pkg/apis/acl"
|
aclapi "github.com/fluxcd/pkg/apis/acl"
|
||||||
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
|
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
@ -134,7 +134,11 @@ func (r *ImageUpdateAutomationReconciler) SetupWithManager(ctx context.Context,
|
||||||
if err := mgr.GetFieldIndexer().IndexField(ctx, &imagev1.ImageUpdateAutomation{}, repoRefKey, func(obj client.Object) []string {
|
if err := mgr.GetFieldIndexer().IndexField(ctx, &imagev1.ImageUpdateAutomation{}, repoRefKey, func(obj client.Object) []string {
|
||||||
updater := obj.(*imagev1.ImageUpdateAutomation)
|
updater := obj.(*imagev1.ImageUpdateAutomation)
|
||||||
ref := updater.Spec.SourceRef
|
ref := updater.Spec.SourceRef
|
||||||
return []string{ref.Name}
|
ns := ref.Namespace
|
||||||
|
if ns == "" {
|
||||||
|
ns = obj.GetNamespace()
|
||||||
|
}
|
||||||
|
return []string{fmt.Sprintf("%s/%s", ns, ref.Name)}
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -148,7 +152,7 @@ func (r *ImageUpdateAutomationReconciler) SetupWithManager(ctx context.Context,
|
||||||
builder.WithPredicates(sourceConfigChangePredicate{}),
|
builder.WithPredicates(sourceConfigChangePredicate{}),
|
||||||
).
|
).
|
||||||
Watches(
|
Watches(
|
||||||
&imagev1_reflect.ImagePolicy{},
|
&reflectorv1.ImagePolicy{},
|
||||||
handler.EnqueueRequestsFromMapFunc(r.automationsForImagePolicy),
|
handler.EnqueueRequestsFromMapFunc(r.automationsForImagePolicy),
|
||||||
builder.WithPredicates(latestImageChangePredicate{}),
|
builder.WithPredicates(latestImageChangePredicate{}),
|
||||||
).
|
).
|
||||||
|
@ -162,8 +166,8 @@ func (r *ImageUpdateAutomationReconciler) SetupWithManager(ctx context.Context,
|
||||||
// particular source.GitRepository object.
|
// particular source.GitRepository object.
|
||||||
func (r *ImageUpdateAutomationReconciler) automationsForGitRepo(ctx context.Context, obj client.Object) []reconcile.Request {
|
func (r *ImageUpdateAutomationReconciler) automationsForGitRepo(ctx context.Context, obj client.Object) []reconcile.Request {
|
||||||
var autoList imagev1.ImageUpdateAutomationList
|
var autoList imagev1.ImageUpdateAutomationList
|
||||||
if err := r.List(ctx, &autoList, client.InNamespace(obj.GetNamespace()),
|
objKey := fmt.Sprintf("%s/%s", obj.GetNamespace(), obj.GetName())
|
||||||
client.MatchingFields{repoRefKey: obj.GetName()}); err != nil {
|
if err := r.List(ctx, &autoList, client.MatchingFields{repoRefKey: objKey}); err != nil {
|
||||||
ctrl.LoggerFrom(ctx).Error(err, "failed to list ImageUpdateAutomations for GitRepository change")
|
ctrl.LoggerFrom(ctx).Error(err, "failed to list ImageUpdateAutomations for GitRepository change")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -396,6 +400,10 @@ func (r *ImageUpdateAutomationReconciler) reconcile(ctx context.Context, sp *pat
|
||||||
if r.features[features.GitShallowClone] {
|
if r.features[features.GitShallowClone] {
|
||||||
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone())
|
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone())
|
||||||
}
|
}
|
||||||
|
if r.features[features.GitSparseCheckout] && obj.Spec.Update.Path != "" {
|
||||||
|
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionSparseCheckoutDirectories(obj.Spec.Update.Path))
|
||||||
|
}
|
||||||
|
|
||||||
// If full sync is still not needed, configure last observed commit to
|
// If full sync is still not needed, configure last observed commit to
|
||||||
// perform optimized clone and obtain a non-concrete commit if the remote
|
// perform optimized clone and obtain a non-concrete commit if the remote
|
||||||
// has not changed.
|
// has not changed.
|
||||||
|
@ -477,6 +485,14 @@ func (r *ImageUpdateAutomationReconciler) reconcile(ctx context.Context, sp *pat
|
||||||
|
|
||||||
pushResult, err = sm.CommitAndPush(ctx, obj, policyResult, pushCfg...)
|
pushResult, err = sm.CommitAndPush(ctx, obj, policyResult, pushCfg...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Check if error is due to removed template field usage.
|
||||||
|
// Set Stalled condition and return nil error to prevent requeue, allowing user to fix template.
|
||||||
|
if errors.Is(err, source.ErrRemovedTemplateField) {
|
||||||
|
conditions.MarkStalled(obj, imagev1.RemovedTemplateFieldReason, "%s", err)
|
||||||
|
result, retErr = ctrl.Result{}, nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
e := fmt.Errorf("failed to update source: %w", err)
|
e := fmt.Errorf("failed to update source: %w", err)
|
||||||
conditions.MarkFalse(obj, meta.ReadyCondition, imagev1.GitOperationFailedReason, "%s", e)
|
conditions.MarkFalse(obj, meta.ReadyCondition, imagev1.GitOperationFailedReason, "%s", e)
|
||||||
result, retErr = ctrl.Result{}, e
|
result, retErr = ctrl.Result{}, e
|
||||||
|
@ -533,7 +549,7 @@ func (r *ImageUpdateAutomationReconciler) reconcileDelete(obj *imagev1.ImageUpda
|
||||||
|
|
||||||
// getPolicies returns list of policies in the given namespace that have latest
|
// getPolicies returns list of policies in the given namespace that have latest
|
||||||
// image.
|
// image.
|
||||||
func getPolicies(ctx context.Context, kclient client.Client, namespace string, selector *metav1.LabelSelector) ([]imagev1_reflect.ImagePolicy, error) {
|
func getPolicies(ctx context.Context, kclient client.Client, namespace string, selector *metav1.LabelSelector) ([]reflectorv1.ImagePolicy, error) {
|
||||||
policySelector := labels.Everything()
|
policySelector := labels.Everything()
|
||||||
var err error
|
var err error
|
||||||
if selector != nil {
|
if selector != nil {
|
||||||
|
@ -542,12 +558,12 @@ func getPolicies(ctx context.Context, kclient client.Client, namespace string, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var policies imagev1_reflect.ImagePolicyList
|
var policies reflectorv1.ImagePolicyList
|
||||||
if err := kclient.List(ctx, &policies, &client.ListOptions{Namespace: namespace, LabelSelector: policySelector}); err != nil {
|
if err := kclient.List(ctx, &policies, &client.ListOptions{Namespace: namespace, LabelSelector: policySelector}); err != nil {
|
||||||
return nil, fmt.Errorf("failed to list policies: %w", err)
|
return nil, fmt.Errorf("failed to list policies: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
readyPolicies := []imagev1_reflect.ImagePolicy{}
|
readyPolicies := []reflectorv1.ImagePolicy{}
|
||||||
for _, policy := range policies.Items {
|
for _, policy := range policies.Items {
|
||||||
// Ignore the policies that don't have a latest image.
|
// Ignore the policies that don't have a latest image.
|
||||||
if policy.Status.LatestRef == nil {
|
if policy.Status.LatestRef == nil {
|
||||||
|
|
|
@ -45,7 +45,7 @@ import (
|
||||||
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
aclapi "github.com/fluxcd/pkg/apis/acl"
|
aclapi "github.com/fluxcd/pkg/apis/acl"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
"github.com/fluxcd/pkg/gittestserver"
|
"github.com/fluxcd/pkg/gittestserver"
|
||||||
|
@ -58,7 +58,6 @@ import (
|
||||||
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/image-automation-controller/internal/source"
|
"github.com/fluxcd/image-automation-controller/internal/source"
|
||||||
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
||||||
"github.com/fluxcd/image-automation-controller/pkg/test"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -71,12 +70,12 @@ const (
|
||||||
Automation: {{ .AutomationObject }}
|
Automation: {{ .AutomationObject }}
|
||||||
|
|
||||||
Files:
|
Files:
|
||||||
{{ range $filename, $_ := .Updated.Files -}}
|
{{ range $filename, $_ := .Changed.FileChanges -}}
|
||||||
- {{ $filename }}
|
- {{ $filename }}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
||||||
Objects:
|
Objects:
|
||||||
{{ range $resource, $_ := .Updated.Objects -}}
|
{{ range $resource, $_ := .Changed.Objects -}}
|
||||||
{{ if eq $resource.Kind "Deployment" -}}
|
{{ if eq $resource.Kind "Deployment" -}}
|
||||||
- {{ $resource.Kind | lower }} {{ $resource.Name | lower }}
|
- {{ $resource.Kind | lower }} {{ $resource.Name | lower }}
|
||||||
{{ else -}}
|
{{ else -}}
|
||||||
|
@ -85,8 +84,10 @@ Objects:
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
||||||
Images:
|
Images:
|
||||||
{{ range .Updated.Images -}}
|
{{ range .Changed.Changes -}}
|
||||||
- {{.}} ({{.Policy.Name}})
|
{{ if .Setter -}}
|
||||||
|
- {{.NewValue}} ({{.Setter}})
|
||||||
|
{{ end -}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
`
|
`
|
||||||
testCommitMessageFmt = `Commit summary
|
testCommitMessageFmt = `Commit summary
|
||||||
|
@ -98,7 +99,7 @@ Files:
|
||||||
Objects:
|
Objects:
|
||||||
- deployment test
|
- deployment test
|
||||||
Images:
|
Images:
|
||||||
- helloworld:v1.0.0 (%s)
|
- helloworld:v1.0.0 (%s:%s)
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -139,12 +140,12 @@ func TestImageUpdateAutomationReconciler_deleteBeforeFinalizer(t *testing.T) {
|
||||||
func TestImageUpdateAutomationReconciler_watchSourceAndLatestImage(t *testing.T) {
|
func TestImageUpdateAutomationReconciler_watchSourceAndLatestImage(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
policySpec := imagev1_reflect.ImagePolicySpec{
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
Name: "not-expected-to-exist",
|
Name: "not-expected-to-exist",
|
||||||
},
|
},
|
||||||
Policy: imagev1_reflect.ImagePolicyChoice{
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
SemVer: &imagev1_reflect.SemVerPolicy{
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
Range: "1.x",
|
Range: "1.x",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -265,12 +266,12 @@ func TestImageUpdateAutomationReconciler_suspended(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageUpdateAutomationReconciler_Reconcile(t *testing.T) {
|
func TestImageUpdateAutomationReconciler_Reconcile(t *testing.T) {
|
||||||
policySpec := imagev1_reflect.ImagePolicySpec{
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
Name: "not-expected-to-exist",
|
Name: "not-expected-to-exist",
|
||||||
},
|
},
|
||||||
Policy: imagev1_reflect.ImagePolicyChoice{
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
SemVer: &imagev1_reflect.SemVerPolicy{
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
Range: "1.x",
|
Range: "1.x",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -705,12 +706,12 @@ func TestImageUpdateAutomationReconciler_Reconcile(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageUpdateAutomationReconciler_commitMessage(t *testing.T) {
|
func TestImageUpdateAutomationReconciler_commitMessage(t *testing.T) {
|
||||||
policySpec := imagev1_reflect.ImagePolicySpec{
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
Name: "not-expected-to-exist",
|
Name: "not-expected-to-exist",
|
||||||
},
|
},
|
||||||
Policy: imagev1_reflect.ImagePolicyChoice{
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
SemVer: &imagev1_reflect.SemVerPolicy{
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
Range: "1.x",
|
Range: "1.x",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -727,7 +728,7 @@ func TestImageUpdateAutomationReconciler_commitMessage(t *testing.T) {
|
||||||
name: "template with update Result",
|
name: "template with update Result",
|
||||||
template: testCommitTemplate,
|
template: testCommitTemplate,
|
||||||
wantCommitMsg: func(policyName, policyNS string) string {
|
wantCommitMsg: func(policyName, policyNS string) string {
|
||||||
return fmt.Sprintf(testCommitMessageFmt, policyNS, policyName)
|
return fmt.Sprintf(testCommitMessageFmt, policyNS, policyNS, policyName)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -841,14 +842,142 @@ Automation: %s/update-test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
|
// TestImageUpdateAutomationReconciler_removedTemplateField tests removed template field usage (.Updated and .Changed.ImageResult).
|
||||||
g := NewWithT(t)
|
func TestImageUpdateAutomationReconciler_removedTemplateField(t *testing.T) {
|
||||||
policySpec := imagev1_reflect.ImagePolicySpec{
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
Name: "not-expected-to-exist",
|
Name: "not-expected-to-exist",
|
||||||
},
|
},
|
||||||
Policy: imagev1_reflect.ImagePolicyChoice{
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
SemVer: &imagev1_reflect.SemVerPolicy{
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
|
Range: "1.x",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fixture := "testdata/appconfig"
|
||||||
|
latest := "helloworld:v1.0.0"
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
template string
|
||||||
|
expectedErrMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: ".Updated field",
|
||||||
|
template: `Commit summary
|
||||||
|
|
||||||
|
Automation: {{ .AutomationObject }}
|
||||||
|
|
||||||
|
Files:
|
||||||
|
{{ range $filename, $_ := .Updated.Files -}}
|
||||||
|
- {{ $filename }}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Objects:
|
||||||
|
{{ range $resource, $_ := .Updated.Objects -}}
|
||||||
|
{{ if eq $resource.Kind "Deployment" -}}
|
||||||
|
- {{ $resource.Kind | lower }} {{ $resource.Name | lower }}
|
||||||
|
{{ else -}}
|
||||||
|
- {{ $resource.Kind }} {{ $resource.Name }}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Images:
|
||||||
|
{{ range .Updated.Images -}}
|
||||||
|
- {{.}} ({{.Policy.Name}})
|
||||||
|
{{ end -}}
|
||||||
|
`,
|
||||||
|
expectedErrMsg: "template uses removed '.Updated' field",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".Changed.ImageResult field",
|
||||||
|
template: `Commit summary
|
||||||
|
|
||||||
|
Automation: {{ .AutomationObject }}
|
||||||
|
|
||||||
|
Files:
|
||||||
|
{{ range $filename, $_ := .Changed.ImageResult.Files -}}
|
||||||
|
- {{ $filename }}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Objects:
|
||||||
|
{{ range $resource, $_ := .Changed.ImageResult.Objects -}}
|
||||||
|
- {{ $resource.Kind }} {{ $resource.Name }}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Images:
|
||||||
|
{{ range .Changed.ImageResult.Images -}}
|
||||||
|
- {{.}} ({{.Policy.Name}})
|
||||||
|
{{ end -}}
|
||||||
|
`,
|
||||||
|
expectedErrMsg: "template uses removed '.Changed.ImageResult' field",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
namespace, err := testEnv.CreateNamespace(ctx, "image-auto-test")
|
||||||
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
|
defer func() { g.Expect(testEnv.Delete(ctx, namespace)).To(Succeed()) }()
|
||||||
|
|
||||||
|
testWithRepoAndImagePolicy(
|
||||||
|
ctx, g, testEnv, namespace.Name, fixture, policySpec, latest,
|
||||||
|
func(g *WithT, s repoAndPolicyArgs, repoURL string, localRepo *extgogit.Repository) {
|
||||||
|
policyKey := types.NamespacedName{
|
||||||
|
Name: s.imagePolicyName,
|
||||||
|
Namespace: s.namespace,
|
||||||
|
}
|
||||||
|
_ = testutil.CommitInRepo(ctx, g, repoURL, s.branch, originRemote, "Install setter marker", func(tmp string) {
|
||||||
|
g.Expect(testutil.ReplaceMarker(filepath.Join(tmp, "deploy.yaml"), policyKey)).To(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
preChangeCommitId := testutil.CommitIdFromBranch(localRepo, s.branch)
|
||||||
|
waitForNewHead(g, localRepo, s.branch, preChangeCommitId)
|
||||||
|
preChangeCommitId = testutil.CommitIdFromBranch(localRepo, s.branch)
|
||||||
|
|
||||||
|
updateStrategy := &imagev1.UpdateStrategy{
|
||||||
|
Strategy: imagev1.UpdateStrategySetters,
|
||||||
|
}
|
||||||
|
err := createImageUpdateAutomation(ctx, testEnv, "update-test", s.namespace, s.gitRepoName, s.gitRepoNamespace, s.branch, s.branch, "", tc.template, "", updateStrategy)
|
||||||
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
|
defer func() {
|
||||||
|
g.Expect(deleteImageUpdateAutomation(ctx, testEnv, "update-test", s.namespace)).To(Succeed())
|
||||||
|
}()
|
||||||
|
|
||||||
|
imageUpdateKey := types.NamespacedName{
|
||||||
|
Namespace: s.namespace,
|
||||||
|
Name: "update-test",
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
var imageUpdate imagev1.ImageUpdateAutomation
|
||||||
|
_ = testEnv.Get(context.TODO(), imageUpdateKey, &imageUpdate)
|
||||||
|
stalledCondition := apimeta.FindStatusCondition(imageUpdate.Status.Conditions, meta.StalledCondition)
|
||||||
|
return stalledCondition != nil &&
|
||||||
|
stalledCondition.Status == metav1.ConditionTrue &&
|
||||||
|
stalledCondition.Reason == imagev1.RemovedTemplateFieldReason &&
|
||||||
|
strings.Contains(stalledCondition.Message, tc.expectedErrMsg)
|
||||||
|
}, timeout).Should(BeTrue())
|
||||||
|
|
||||||
|
head, _ := localRepo.Head()
|
||||||
|
g.Expect(head.Hash().String()).To(Equal(preChangeCommitId))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
|
Name: "not-expected-to-exist",
|
||||||
|
},
|
||||||
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
Range: "1.x",
|
Range: "1.x",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -875,7 +1004,7 @@ func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
|
||||||
testWithCustomRepoAndImagePolicy(
|
testWithCustomRepoAndImagePolicy(
|
||||||
ctx, g, testEnv, fixture, policySpec, latest, args,
|
ctx, g, testEnv, fixture, policySpec, latest, args,
|
||||||
func(g *WithT, s repoAndPolicyArgs, repoURL string, localRepo *extgogit.Repository) {
|
func(g *WithT, s repoAndPolicyArgs, repoURL string, localRepo *extgogit.Repository) {
|
||||||
commitMessage := fmt.Sprintf(testCommitMessageFmt, s.namespace, s.imagePolicyName)
|
commitMessage := fmt.Sprintf(testCommitMessageFmt, s.namespace, s.namespace, s.imagePolicyName)
|
||||||
|
|
||||||
// Update the setter marker in the repo.
|
// Update the setter marker in the repo.
|
||||||
policyKey := types.NamespacedName{
|
policyKey := types.NamespacedName{
|
||||||
|
@ -926,7 +1055,7 @@ func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
|
||||||
r := &ImageUpdateAutomationReconciler{
|
r := &ImageUpdateAutomationReconciler{
|
||||||
Client: fakeclient.NewClientBuilder().
|
Client: fakeclient.NewClientBuilder().
|
||||||
WithScheme(testEnv.Scheme()).
|
WithScheme(testEnv.Scheme()).
|
||||||
WithStatusSubresource(&imagev1.ImageUpdateAutomation{}, &imagev1_reflect.ImagePolicy{}).
|
WithStatusSubresource(&imagev1.ImageUpdateAutomation{}, &reflectorv1.ImagePolicy{}).
|
||||||
Build(),
|
Build(),
|
||||||
EventRecorder: testEnv.GetEventRecorderFor("image-automation-controller"),
|
EventRecorder: testEnv.GetEventRecorderFor("image-automation-controller"),
|
||||||
NoCrossNamespaceRef: true,
|
NoCrossNamespaceRef: true,
|
||||||
|
@ -975,12 +1104,12 @@ func TestImageUpdateAutomationReconciler_crossNamespaceRef(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageUpdateAutomationReconciler_updatePath(t *testing.T) {
|
func TestImageUpdateAutomationReconciler_updatePath(t *testing.T) {
|
||||||
policySpec := imagev1_reflect.ImagePolicySpec{
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
Name: "not-expected-to-exist",
|
Name: "not-expected-to-exist",
|
||||||
},
|
},
|
||||||
Policy: imagev1_reflect.ImagePolicyChoice{
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
SemVer: &imagev1_reflect.SemVerPolicy{
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
Range: "1.x",
|
Range: "1.x",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1057,12 +1186,12 @@ func TestImageUpdateAutomationReconciler_updatePath(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageUpdateAutomationReconciler_signedCommit(t *testing.T) {
|
func TestImageUpdateAutomationReconciler_signedCommit(t *testing.T) {
|
||||||
policySpec := imagev1_reflect.ImagePolicySpec{
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
Name: "not-expected-to-exist",
|
Name: "not-expected-to-exist",
|
||||||
},
|
},
|
||||||
Policy: imagev1_reflect.ImagePolicyChoice{
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
SemVer: &imagev1_reflect.SemVerPolicy{
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
Range: "1.x",
|
Range: "1.x",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1279,7 +1408,7 @@ func TestImageUpdateAutomationReconciler_e2e(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageUpdateAutomationReconciler_defaulting(t *testing.T) {
|
func TestImageUpdateAutomationReconciler_DefaultUpdate(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
branch := rand.String(8)
|
branch := rand.String(8)
|
||||||
|
@ -1338,6 +1467,70 @@ func TestImageUpdateAutomationReconciler_defaulting(t *testing.T) {
|
||||||
To(Equal(&imagev1.UpdateStrategy{Strategy: imagev1.UpdateStrategySetters}))
|
To(Equal(&imagev1.UpdateStrategy{Strategy: imagev1.UpdateStrategySetters}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImageUpdateAutomationReconciler_DefaultStrategy(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
branch := rand.String(8)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Create a test namespace.
|
||||||
|
namespace, err := testEnv.CreateNamespace(ctx, "image-auto-test")
|
||||||
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
|
defer func() { g.Expect(testEnv.Delete(ctx, namespace)).To(Succeed()) }()
|
||||||
|
|
||||||
|
// Create an instance of ImageUpdateAutomation.
|
||||||
|
key := types.NamespacedName{
|
||||||
|
Name: "update-" + rand.String(5),
|
||||||
|
Namespace: namespace.Name,
|
||||||
|
}
|
||||||
|
auto := &imagev1.ImageUpdateAutomation{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: key.Name,
|
||||||
|
Namespace: key.Namespace,
|
||||||
|
},
|
||||||
|
Spec: imagev1.ImageUpdateAutomationSpec{
|
||||||
|
SourceRef: imagev1.CrossNamespaceSourceReference{
|
||||||
|
Kind: "GitRepository",
|
||||||
|
Name: "garbage",
|
||||||
|
},
|
||||||
|
Interval: metav1.Duration{Duration: 2 * time.Hour},
|
||||||
|
GitSpec: &imagev1.GitSpec{
|
||||||
|
Checkout: &imagev1.GitCheckoutSpec{
|
||||||
|
Reference: sourcev1.GitRepositoryRef{
|
||||||
|
Branch: branch,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Commit: imagev1.CommitSpec{
|
||||||
|
Author: imagev1.CommitUser{
|
||||||
|
Email: testAuthorEmail,
|
||||||
|
},
|
||||||
|
MessageTemplate: "nothing",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Update: &imagev1.UpdateStrategy{
|
||||||
|
Path: "./test-path",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
g.Expect(testEnv.Create(ctx, auto)).To(Succeed())
|
||||||
|
defer func() {
|
||||||
|
g.Expect(testEnv.Delete(ctx, auto)).To(Succeed())
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Should default .spec.update to {strategy: Setters}.
|
||||||
|
var fetchedAuto imagev1.ImageUpdateAutomation
|
||||||
|
g.Eventually(func() bool {
|
||||||
|
err := testEnv.Get(ctx, key, &fetchedAuto)
|
||||||
|
return err == nil
|
||||||
|
}, timeout, time.Second).Should(BeTrue())
|
||||||
|
g.Expect(fetchedAuto.Spec.Update).
|
||||||
|
To(Equal(&imagev1.UpdateStrategy{
|
||||||
|
Strategy: imagev1.UpdateStrategySetters,
|
||||||
|
Path: "./test-path",
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
func TestImageUpdateAutomationReconciler_notify(t *testing.T) {
|
func TestImageUpdateAutomationReconciler_notify(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
testPushResult, err := source.NewPushResult("branch", "rev", "test commit message")
|
testPushResult, err := source.NewPushResult("branch", "rev", "test commit message")
|
||||||
|
@ -1528,10 +1721,10 @@ func Test_getPolicies(t *testing.T) {
|
||||||
// Create all the test policies.
|
// Create all the test policies.
|
||||||
testObjects := []client.Object{}
|
testObjects := []client.Object{}
|
||||||
for _, p := range tt.policies {
|
for _, p := range tt.policies {
|
||||||
aPolicy := &imagev1_reflect.ImagePolicy{}
|
aPolicy := &reflectorv1.ImagePolicy{}
|
||||||
aPolicy.Name = p.name
|
aPolicy.Name = p.name
|
||||||
aPolicy.Namespace = p.namespace
|
aPolicy.Namespace = p.namespace
|
||||||
aPolicy.Status = imagev1_reflect.ImagePolicyStatus{
|
aPolicy.Status = reflectorv1.ImagePolicyStatus{
|
||||||
LatestRef: testutil.ImageToRef(p.latestImage),
|
LatestRef: testutil.ImageToRef(p.latestImage),
|
||||||
}
|
}
|
||||||
aPolicy.Labels = p.labels
|
aPolicy.Labels = p.labels
|
||||||
|
@ -1652,7 +1845,7 @@ func compareRepoWithExpected(ctx context.Context, g *WithT, repoURL, branch, fix
|
||||||
defer wt.Filesystem.Remove(".")
|
defer wt.Filesystem.Remove(".")
|
||||||
|
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
test.ExpectMatchingDirectories(g, wt.Filesystem.Root(), expected)
|
testutil.ExpectMatchingDirectories(g, wt.Filesystem.Root(), expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForNewHead(g *WithT, repo *extgogit.Repository, branch, preChangeHash string) {
|
func waitForNewHead(g *WithT, repo *extgogit.Repository, branch, preChangeHash string) {
|
||||||
|
@ -1744,7 +1937,7 @@ func testWithRepoAndImagePolicy(
|
||||||
kClient client.Client,
|
kClient client.Client,
|
||||||
namespace string,
|
namespace string,
|
||||||
fixture string,
|
fixture string,
|
||||||
policySpec imagev1_reflect.ImagePolicySpec,
|
policySpec reflectorv1.ImagePolicySpec,
|
||||||
latest string,
|
latest string,
|
||||||
testFunc testWithRepoAndImagePolicyTestFunc) {
|
testFunc testWithRepoAndImagePolicyTestFunc) {
|
||||||
// Generate unique repo and policy arguments.
|
// Generate unique repo and policy arguments.
|
||||||
|
@ -1761,7 +1954,7 @@ func testWithCustomRepoAndImagePolicy(
|
||||||
g *WithT,
|
g *WithT,
|
||||||
kClient client.Client,
|
kClient client.Client,
|
||||||
fixture string,
|
fixture string,
|
||||||
policySpec imagev1_reflect.ImagePolicySpec,
|
policySpec reflectorv1.ImagePolicySpec,
|
||||||
latest string,
|
latest string,
|
||||||
args repoAndPolicyArgs,
|
args repoAndPolicyArgs,
|
||||||
testFunc testWithRepoAndImagePolicyTestFunc) {
|
testFunc testWithRepoAndImagePolicyTestFunc) {
|
||||||
|
@ -1819,12 +2012,12 @@ func createGitRepository(ctx context.Context, kClient client.Client, name, names
|
||||||
}
|
}
|
||||||
|
|
||||||
func createImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, repoRef, semverRange, latest string) error {
|
func createImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, repoRef, semverRange, latest string) error {
|
||||||
policySpec := imagev1_reflect.ImagePolicySpec{
|
policySpec := reflectorv1.ImagePolicySpec{
|
||||||
ImageRepositoryRef: meta.NamespacedObjectReference{
|
ImageRepositoryRef: meta.NamespacedObjectReference{
|
||||||
Name: repoRef,
|
Name: repoRef,
|
||||||
},
|
},
|
||||||
Policy: imagev1_reflect.ImagePolicyChoice{
|
Policy: reflectorv1.ImagePolicyChoice{
|
||||||
SemVer: &imagev1_reflect.SemVerPolicy{
|
SemVer: &reflectorv1.SemVerPolicy{
|
||||||
Range: semverRange,
|
Range: semverRange,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1832,8 +2025,8 @@ func createImagePolicyWithLatestImage(ctx context.Context, kClient client.Client
|
||||||
return createImagePolicyWithLatestImageForSpec(ctx, kClient, name, namespace, policySpec, latest)
|
return createImagePolicyWithLatestImageForSpec(ctx, kClient, name, namespace, policySpec, latest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createImagePolicyWithLatestImageForSpec(ctx context.Context, kClient client.Client, name, namespace string, policySpec imagev1_reflect.ImagePolicySpec, latest string) error {
|
func createImagePolicyWithLatestImageForSpec(ctx context.Context, kClient client.Client, name, namespace string, policySpec reflectorv1.ImagePolicySpec, latest string) error {
|
||||||
policy := &imagev1_reflect.ImagePolicy{
|
policy := &reflectorv1.ImagePolicy{
|
||||||
Spec: policySpec,
|
Spec: policySpec,
|
||||||
}
|
}
|
||||||
policy.Name = name
|
policy.Name = name
|
||||||
|
@ -1848,7 +2041,7 @@ func createImagePolicyWithLatestImageForSpec(ctx context.Context, kClient client
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, latest string) error {
|
func updateImagePolicyWithLatestImage(ctx context.Context, kClient client.Client, name, namespace, latest string) error {
|
||||||
policy := &imagev1_reflect.ImagePolicy{}
|
policy := &reflectorv1.ImagePolicy{}
|
||||||
key := types.NamespacedName{
|
key := types.NamespacedName{
|
||||||
Name: name,
|
Name: name,
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
|
@ -1913,7 +2106,7 @@ func deleteImageUpdateAutomation(ctx context.Context, kClient client.Client, nam
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteImagePolicy(ctx context.Context, kClient client.Client, name, namespace string) error {
|
func deleteImagePolicy(ctx context.Context, kClient client.Client, name, namespace string) error {
|
||||||
imagePolicy := &imagev1_reflect.ImagePolicy{}
|
imagePolicy := &reflectorv1.ImagePolicy{}
|
||||||
imagePolicy.Name = name
|
imagePolicy.Name = name
|
||||||
imagePolicy.Namespace = namespace
|
imagePolicy.Namespace = namespace
|
||||||
return kClient.Delete(ctx, imagePolicy)
|
return kClient.Delete(ctx, imagePolicy)
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// latestImageChangePredicate implements a predicate for latest image change.
|
// latestImageChangePredicate implements a predicate for latest image change.
|
||||||
|
@ -43,12 +43,12 @@ func (latestImageChangePredicate) Update(e event.UpdateEvent) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
oldSource, ok := e.ObjectOld.(*imagev1_reflect.ImagePolicy)
|
oldSource, ok := e.ObjectOld.(*reflectorv1.ImagePolicy)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
newSource, ok := e.ObjectNew.(*imagev1_reflect.ImagePolicy)
|
newSource, ok := e.ObjectNew.(*reflectorv1.ImagePolicy)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,19 +22,19 @@ import (
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_latestImageChangePredicate_Update(t *testing.T) {
|
func Test_latestImageChangePredicate_Update(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
beforeFunc func(oldObj, newObj *imagev1_reflect.ImagePolicy)
|
beforeFunc func(oldObj, newObj *reflectorv1.ImagePolicy)
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "no latest image",
|
name: "no latest image",
|
||||||
beforeFunc: func(oldObj, newObj *imagev1_reflect.ImagePolicy) {
|
beforeFunc: func(oldObj, newObj *reflectorv1.ImagePolicy) {
|
||||||
oldObj.Status.LatestRef = nil
|
oldObj.Status.LatestRef = nil
|
||||||
newObj.Status.LatestRef = nil
|
newObj.Status.LatestRef = nil
|
||||||
},
|
},
|
||||||
|
@ -42,17 +42,17 @@ func Test_latestImageChangePredicate_Update(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "new image, no old image",
|
name: "new image, no old image",
|
||||||
beforeFunc: func(oldObj, newObj *imagev1_reflect.ImagePolicy) {
|
beforeFunc: func(oldObj, newObj *reflectorv1.ImagePolicy) {
|
||||||
oldObj.Status.LatestRef = nil
|
oldObj.Status.LatestRef = nil
|
||||||
newObj.Status.LatestRef = &imagev1_reflect.ImageRef{Name: "foo"}
|
newObj.Status.LatestRef = &reflectorv1.ImageRef{Name: "foo"}
|
||||||
},
|
},
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "different old and new image",
|
name: "different old and new image",
|
||||||
beforeFunc: func(oldObj, newObj *imagev1_reflect.ImagePolicy) {
|
beforeFunc: func(oldObj, newObj *reflectorv1.ImagePolicy) {
|
||||||
oldObj.Status.LatestRef = &imagev1_reflect.ImageRef{Name: "bar"}
|
oldObj.Status.LatestRef = &reflectorv1.ImageRef{Name: "bar"}
|
||||||
newObj.Status.LatestRef = &imagev1_reflect.ImageRef{Name: "foo"}
|
newObj.Status.LatestRef = &reflectorv1.ImageRef{Name: "foo"}
|
||||||
},
|
},
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
|
@ -61,7 +61,7 @@ func Test_latestImageChangePredicate_Update(t *testing.T) {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
oldObj := &imagev1_reflect.ImagePolicy{}
|
oldObj := &reflectorv1.ImagePolicy{}
|
||||||
newObj := oldObj.DeepCopy()
|
newObj := oldObj.DeepCopy()
|
||||||
if tt.beforeFunc != nil {
|
if tt.beforeFunc != nil {
|
||||||
tt.beforeFunc(oldObj, newObj)
|
tt.beforeFunc(oldObj, newObj)
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/pkg/runtime/controller"
|
"github.com/fluxcd/pkg/runtime/controller"
|
||||||
"github.com/fluxcd/pkg/runtime/testenv"
|
"github.com/fluxcd/pkg/runtime/testenv"
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
|
@ -56,7 +56,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
utilruntime.Must(imagev1_reflect.AddToScheme(scheme.Scheme))
|
utilruntime.Must(reflectorv1.AddToScheme(scheme.Scheme))
|
||||||
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
|
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
|
||||||
utilruntime.Must(imagev1.AddToScheme(scheme.Scheme))
|
utilruntime.Must(imagev1.AddToScheme(scheme.Scheme))
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,9 @@ const (
|
||||||
// GitAllBranchReferences enables the download of all branch head references
|
// GitAllBranchReferences enables the download of all branch head references
|
||||||
// when push branches are configured. When enabled fixes fluxcd/flux2#3384.
|
// when push branches are configured. When enabled fixes fluxcd/flux2#3384.
|
||||||
GitAllBranchReferences = "GitAllBranchReferences"
|
GitAllBranchReferences = "GitAllBranchReferences"
|
||||||
|
// GitSparseCheckout enables the use of sparse checkout when pulling source from
|
||||||
|
// Git repositories.
|
||||||
|
GitSparseCheckout = "GitSparseCheckout"
|
||||||
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
|
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
|
||||||
// be cached.
|
// be cached.
|
||||||
//
|
//
|
||||||
|
@ -55,6 +58,10 @@ var features = map[string]bool{
|
||||||
// opt-out from v0.28
|
// opt-out from v0.28
|
||||||
GitAllBranchReferences: true,
|
GitAllBranchReferences: true,
|
||||||
|
|
||||||
|
// GitSparseCheckout
|
||||||
|
// opt-in from v0.42
|
||||||
|
GitSparseCheckout: false,
|
||||||
|
|
||||||
// CacheSecretsAndConfigMaps
|
// CacheSecretsAndConfigMaps
|
||||||
// opt-in from v0.29
|
// opt-in from v0.29
|
||||||
CacheSecretsAndConfigMaps: false,
|
CacheSecretsAndConfigMaps: false,
|
||||||
|
|
|
@ -25,10 +25,10 @@ import (
|
||||||
"github.com/fluxcd/pkg/runtime/logger"
|
"github.com/fluxcd/pkg/runtime/logger"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
|
|
||||||
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/image-automation-controller/pkg/update"
|
"github.com/fluxcd/image-automation-controller/internal/update"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -42,8 +42,8 @@ var (
|
||||||
|
|
||||||
// ApplyPolicies applies the given set of policies on the source present in the
|
// ApplyPolicies applies the given set of policies on the source present in the
|
||||||
// workDir based on the provided ImageUpdateAutomation configuration.
|
// workDir based on the provided ImageUpdateAutomation configuration.
|
||||||
func ApplyPolicies(ctx context.Context, workDir string, obj *imagev1.ImageUpdateAutomation, policies []imagev1_reflect.ImagePolicy) (update.ResultV2, error) {
|
func ApplyPolicies(ctx context.Context, workDir string, obj *imagev1.ImageUpdateAutomation, policies []reflectorv1.ImagePolicy) (update.Result, error) {
|
||||||
var result update.ResultV2
|
var result update.Result
|
||||||
if obj.Spec.Update == nil {
|
if obj.Spec.Update == nil {
|
||||||
return result, ErrNoUpdateStrategy
|
return result, ErrNoUpdateStrategy
|
||||||
}
|
}
|
||||||
|
@ -62,5 +62,5 @@ func ApplyPolicies(ctx context.Context, workDir string, obj *imagev1.ImageUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
tracelog := log.FromContext(ctx).V(logger.TraceLevel)
|
tracelog := log.FromContext(ctx).V(logger.TraceLevel)
|
||||||
return update.UpdateV2WithSetters(tracelog, manifestPath, manifestPath, policies)
|
return update.UpdateWithSetters(tracelog, manifestPath, manifestPath, policies)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,10 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
|
|
||||||
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
||||||
"github.com/fluxcd/image-automation-controller/pkg/test"
|
|
||||||
"github.com/fluxcd/image-automation-controller/pkg/update"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func testdataPath(path string) string {
|
func testdataPath(path string) string {
|
||||||
|
@ -48,7 +46,6 @@ func Test_applyPolicies(t *testing.T) {
|
||||||
inputPath string
|
inputPath string
|
||||||
expectedPath string
|
expectedPath string
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantResult update.Result
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid update strategy and one policy",
|
name: "valid update strategy and one policy",
|
||||||
|
@ -118,12 +115,12 @@ func Test_applyPolicies(t *testing.T) {
|
||||||
workDir := t.TempDir()
|
workDir := t.TempDir()
|
||||||
|
|
||||||
// Create all the policy objects.
|
// Create all the policy objects.
|
||||||
policyList := []imagev1_reflect.ImagePolicy{}
|
policyList := []reflectorv1.ImagePolicy{}
|
||||||
for name, image := range tt.policyLatestImages {
|
for name, image := range tt.policyLatestImages {
|
||||||
policy := &imagev1_reflect.ImagePolicy{}
|
policy := &reflectorv1.ImagePolicy{}
|
||||||
policy.Name = name
|
policy.Name = name
|
||||||
policy.Namespace = testNS
|
policy.Namespace = testNS
|
||||||
policy.Status = imagev1_reflect.ImagePolicyStatus{
|
policy.Status = reflectorv1.ImagePolicyStatus{
|
||||||
LatestRef: testutil.ImageToRef(image),
|
LatestRef: testutil.ImageToRef(image),
|
||||||
}
|
}
|
||||||
policyList = append(policyList, *policy)
|
policyList = append(policyList, *policy)
|
||||||
|
@ -150,7 +147,7 @@ func Test_applyPolicies(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme := runtime.NewScheme()
|
scheme := runtime.NewScheme()
|
||||||
imagev1_reflect.AddToScheme(scheme)
|
reflectorv1.AddToScheme(scheme)
|
||||||
imagev1.AddToScheme(scheme)
|
imagev1.AddToScheme(scheme)
|
||||||
|
|
||||||
_, err := ApplyPolicies(context.TODO(), workDir, updateAuto, policyList)
|
_, err := ApplyPolicies(context.TODO(), workDir, updateAuto, policyList)
|
||||||
|
@ -166,7 +163,7 @@ func Test_applyPolicies(t *testing.T) {
|
||||||
} else {
|
} else {
|
||||||
g.Expect(testutil.ReplaceMarker(filepath.Join(expected, "deploy.yaml"), targetPolicyKey)).ToNot(HaveOccurred())
|
g.Expect(testutil.ReplaceMarker(filepath.Join(expected, "deploy.yaml"), targetPolicyKey)).ToNot(HaveOccurred())
|
||||||
}
|
}
|
||||||
test.ExpectMatchingDirectories(g, workDir, expected)
|
testutil.ExpectMatchingDirectories(g, workDir, expected)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ProtonMail/go-crypto/openpgp"
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
|
"github.com/fluxcd/pkg/runtime/secrets"
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
@ -62,13 +63,14 @@ type gitSrcCfg struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildGitConfig(ctx context.Context, c client.Client, originKey, srcKey types.NamespacedName, gitSpec *imagev1.GitSpec, opts SourceOptions) (*gitSrcCfg, error) {
|
func buildGitConfig(ctx context.Context, c client.Client, originKey, srcKey types.NamespacedName, gitSpec *imagev1.GitSpec, opts SourceOptions) (*gitSrcCfg, error) {
|
||||||
|
var err error
|
||||||
cfg := &gitSrcCfg{
|
cfg := &gitSrcCfg{
|
||||||
srcKey: srcKey,
|
srcKey: srcKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the repo.
|
// Get the repo.
|
||||||
repo := &sourcev1.GitRepository{}
|
repo := &sourcev1.GitRepository{}
|
||||||
if err := c.Get(ctx, srcKey, repo); err != nil {
|
if err = c.Get(ctx, srcKey, repo); err != nil {
|
||||||
if client.IgnoreNotFound(err) == nil {
|
if client.IgnoreNotFound(err) == nil {
|
||||||
return nil, fmt.Errorf("referenced git repository does not exist: %w", err)
|
return nil, fmt.Errorf("referenced git repository does not exist: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -94,14 +96,26 @@ func buildGitConfig(ctx context.Context, c client.Client, originKey, srcKey type
|
||||||
|
|
||||||
// Configure push first as the client options below depend on the push
|
// Configure push first as the client options below depend on the push
|
||||||
// configuration.
|
// configuration.
|
||||||
if err := configurePush(cfg, gitSpec, cfg.checkoutRef); err != nil {
|
if err = configurePush(cfg, gitSpec, cfg.checkoutRef); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyOpts, proxyURL, err := getProxyOpts(ctx, c, repo)
|
var proxyURL *url.URL
|
||||||
if err != nil {
|
var proxyOpts *transport.ProxyOptions
|
||||||
return nil, err
|
// Check if a proxy secret reference is provided in the GitRepository spec.
|
||||||
|
if repo.Spec.ProxySecretRef != nil {
|
||||||
|
secretRef := types.NamespacedName{
|
||||||
|
Name: repo.Spec.ProxySecretRef.Name,
|
||||||
|
Namespace: repo.GetNamespace(),
|
||||||
|
}
|
||||||
|
// Get the proxy URL from runtime/secret
|
||||||
|
proxyURL, err = secrets.ProxyURLFromSecretRef(ctx, c, secretRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
proxyOpts = &transport.ProxyOptions{URL: proxyURL.String()}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.authOpts, err = getAuthOpts(ctx, c, repo, opts, proxyURL)
|
cfg.authOpts, err = getAuthOpts(ctx, c, repo, opts, proxyURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -165,13 +179,15 @@ func configurePush(cfg *gitSrcCfg, gitSpec *imagev1.GitSpec, checkoutRef *source
|
||||||
|
|
||||||
func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitRepository,
|
func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitRepository,
|
||||||
srcOpts SourceOptions, proxyURL *url.URL) (*git.AuthOptions, error) {
|
srcOpts SourceOptions, proxyURL *url.URL) (*git.AuthOptions, error) {
|
||||||
|
var secret *corev1.Secret
|
||||||
var data map[string][]byte
|
var data map[string][]byte
|
||||||
var err error
|
var err error
|
||||||
if repo.Spec.SecretRef != nil {
|
if repo.Spec.SecretRef != nil {
|
||||||
data, err = getSecretData(ctx, c, repo.Spec.SecretRef.Name, repo.GetNamespace())
|
secret, err = getSecret(ctx, c, repo.Spec.SecretRef.Name, repo.GetNamespace())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get auth secret '%s/%s': %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, err)
|
return nil, fmt.Errorf("failed to get auth secret '%s/%s': %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, err)
|
||||||
}
|
}
|
||||||
|
data = secret.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := url.Parse(repo.Spec.URL)
|
u, err := url.Parse(repo.Spec.URL)
|
||||||
|
@ -188,7 +204,10 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
|
||||||
switch provider := repo.GetProvider(); provider {
|
switch provider := repo.GetProvider(); provider {
|
||||||
case sourcev1.GitProviderAzure: // If AWS or GCP are added in the future they can be added here separated by a comma.
|
case sourcev1.GitProviderAzure: // If AWS or GCP are added in the future they can be added here separated by a comma.
|
||||||
getCreds = func() (*authutils.GitCredentials, error) {
|
getCreds = func() (*authutils.GitCredentials, error) {
|
||||||
var opts []auth.Option
|
opts := []auth.Option{
|
||||||
|
auth.WithClient(c),
|
||||||
|
auth.WithServiceAccountNamespace(srcOpts.objNamespace),
|
||||||
|
}
|
||||||
|
|
||||||
if srcOpts.tokenCache != nil {
|
if srcOpts.tokenCache != nil {
|
||||||
involvedObject := cache.InvolvedObject{
|
involvedObject := cache.InvolvedObject{
|
||||||
|
@ -211,24 +230,33 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
|
||||||
if repo.Spec.SecretRef == nil {
|
if repo.Spec.SecretRef == nil {
|
||||||
return nil, fmt.Errorf("secretRef with github app data must be specified when provider is set to github: %w", ErrInvalidSourceConfiguration)
|
return nil, fmt.Errorf("secretRef with github app data must be specified when provider is set to github: %w", ErrInvalidSourceConfiguration)
|
||||||
}
|
}
|
||||||
|
authMethods, err := secrets.AuthMethodsFromSecret(ctx, secret, secrets.WithTLSSystemCertPool())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !authMethods.HasGitHubAppData() {
|
||||||
|
return nil, fmt.Errorf("secretRef with github app data must be specified when provider is set to github: %w", ErrInvalidSourceConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
getCreds = func() (*authutils.GitCredentials, error) {
|
getCreds = func() (*authutils.GitCredentials, error) {
|
||||||
var opts []github.OptFunc
|
var appOpts []github.OptFunc
|
||||||
|
|
||||||
if len(data) > 0 {
|
appOpts = append(appOpts, github.WithAppData(authMethods.GitHubAppData))
|
||||||
opts = append(opts, github.WithAppData(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
if proxyURL != nil {
|
if proxyURL != nil {
|
||||||
opts = append(opts, github.WithProxyURL(proxyURL))
|
appOpts = append(appOpts, github.WithProxyURL(proxyURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
if srcOpts.tokenCache != nil {
|
if srcOpts.tokenCache != nil {
|
||||||
opts = append(opts, github.WithCache(srcOpts.tokenCache, imagev1.ImageUpdateAutomationKind,
|
appOpts = append(appOpts, github.WithCache(srcOpts.tokenCache, imagev1.ImageUpdateAutomationKind,
|
||||||
srcOpts.objName, srcOpts.objNamespace, cache.OperationReconcile))
|
srcOpts.objName, srcOpts.objNamespace, cache.OperationReconcile))
|
||||||
}
|
}
|
||||||
|
|
||||||
username, password, err := github.GetCredentials(ctx, opts...)
|
if authMethods.HasTLS() {
|
||||||
|
appOpts = append(appOpts, github.WithTLSConfig(authMethods.TLS))
|
||||||
|
}
|
||||||
|
|
||||||
|
username, password, err := github.GetCredentials(ctx, appOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -239,7 +267,7 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// analyze secret, if it has github app data, perhaps provider should have been github.
|
// analyze secret, if it has github app data, perhaps provider should have been github.
|
||||||
if appID := data[github.AppIDKey]; len(appID) != 0 {
|
if appID := data[github.KeyAppID]; len(appID) != 0 {
|
||||||
return nil, fmt.Errorf("secretRef '%s/%s' has github app data but provider is not set to github: %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, ErrInvalidSourceConfiguration)
|
return nil, fmt.Errorf("secretRef '%s/%s' has github app data but provider is not set to github: %w", repo.GetNamespace(), repo.Spec.SecretRef.Name, ErrInvalidSourceConfiguration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,45 +283,6 @@ func getAuthOpts(ctx context.Context, c client.Client, repo *sourcev1.GitReposit
|
||||||
return opts, nil
|
return opts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProxyOpts(ctx context.Context, c client.Client, repo *sourcev1.GitRepository) (*transport.ProxyOptions, *url.URL, error) {
|
|
||||||
if repo.Spec.ProxySecretRef == nil {
|
|
||||||
return nil, nil, nil
|
|
||||||
}
|
|
||||||
name := repo.Spec.ProxySecretRef.Name
|
|
||||||
namespace := repo.GetNamespace()
|
|
||||||
proxyData, err := getSecretData(ctx, c, name, namespace)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failed to get proxy secret '%s/%s': %w", namespace, name, err)
|
|
||||||
}
|
|
||||||
b, ok := proxyData["address"]
|
|
||||||
if !ok {
|
|
||||||
return nil, nil, fmt.Errorf("invalid proxy secret '%s/%s': key 'address' is missing", namespace, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
address := string(b)
|
|
||||||
username := string(proxyData["username"])
|
|
||||||
password := string(proxyData["password"])
|
|
||||||
|
|
||||||
proxyOpts := &transport.ProxyOptions{
|
|
||||||
URL: address,
|
|
||||||
Username: username,
|
|
||||||
Password: password,
|
|
||||||
}
|
|
||||||
|
|
||||||
proxyURL, err := url.Parse(string(address))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("invalid address in proxy secret '%s/%s': %w", namespace, name, err)
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case username != "" && password == "":
|
|
||||||
proxyURL.User = url.User(username)
|
|
||||||
case username != "" && password != "":
|
|
||||||
proxyURL.User = url.UserPassword(username, password)
|
|
||||||
}
|
|
||||||
|
|
||||||
return proxyOpts, proxyURL, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSigningEntity(ctx context.Context, c client.Client, namespace string, gitSpec *imagev1.GitSpec) (*openpgp.Entity, error) {
|
func getSigningEntity(ctx context.Context, c client.Client, namespace string, gitSpec *imagev1.GitSpec) (*openpgp.Entity, error) {
|
||||||
secretName := gitSpec.Commit.SigningKey.SecretRef.Name
|
secretName := gitSpec.Commit.SigningKey.SecretRef.Name
|
||||||
secretData, err := getSecretData(ctx, c, secretName, namespace)
|
secretData, err := getSecretData(ctx, c, secretName, namespace)
|
||||||
|
@ -330,13 +319,21 @@ func getSigningEntity(ctx context.Context, c client.Client, namespace string, gi
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSecretData(ctx context.Context, c client.Client, name, namespace string) (map[string][]byte, error) {
|
func getSecretData(ctx context.Context, c client.Client, name, namespace string) (map[string][]byte, error) {
|
||||||
key := types.NamespacedName{
|
secret, err := getSecret(ctx, c, name, namespace)
|
||||||
Namespace: namespace,
|
if err != nil {
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
var secret corev1.Secret
|
|
||||||
if err := c.Get(ctx, key, &secret); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return secret.Data, nil
|
return secret.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSecret(ctx context.Context, c client.Client, name, namespace string) (*corev1.Secret, error) {
|
||||||
|
key := types.NamespacedName{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
secret := &corev1.Secret{}
|
||||||
|
if err := c.Get(ctx, key, secret); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return secret, nil
|
||||||
|
}
|
||||||
|
|
|
@ -19,11 +19,9 @@ package source
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
@ -32,12 +30,13 @@ import (
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
|
|
||||||
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
|
||||||
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
"github.com/fluxcd/pkg/git"
|
"github.com/fluxcd/pkg/git"
|
||||||
"github.com/fluxcd/pkg/git/github"
|
"github.com/fluxcd/pkg/git/github"
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
|
|
||||||
|
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
||||||
|
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_getAuthOpts(t *testing.T) {
|
func Test_getAuthOpts(t *testing.T) {
|
||||||
|
@ -183,9 +182,9 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
|
||||||
Name: "githubAppSecret",
|
Name: "githubAppSecret",
|
||||||
},
|
},
|
||||||
Data: map[string][]byte{
|
Data: map[string][]byte{
|
||||||
github.AppIDKey: []byte("123"),
|
github.KeyAppID: []byte("123"),
|
||||||
github.AppInstallationIDKey: []byte("456"),
|
github.KeyAppInstallationID: []byte("456"),
|
||||||
github.AppPrivateKey: []byte("abc"),
|
github.KeyAppPrivateKey: []byte("abc"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
@ -196,6 +195,26 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
|
||||||
},
|
},
|
||||||
wantErr: "Key must be a PEM encoded PKCS1 or PKCS8 key",
|
wantErr: "Key must be a PEM encoded PKCS1 or PKCS8 key",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "github provider with basic auth in secret",
|
||||||
|
url: "https://example.com/org/repo",
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "basic-auth-secret",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"username": []byte("abc"),
|
||||||
|
"password": []byte(""),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Spec.Provider = sourcev1.GitProviderGitHub
|
||||||
|
obj.Spec.SecretRef = &meta.LocalObjectReference{
|
||||||
|
Name: "basic-auth-secret",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wantErr: "secretRef with github app data must be specified when provider is set to github",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "generic provider with github app data in secret",
|
name: "generic provider with github app data in secret",
|
||||||
url: "https://example.com/org/repo",
|
url: "https://example.com/org/repo",
|
||||||
|
@ -204,7 +223,7 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
|
||||||
Name: "githubAppSecret",
|
Name: "githubAppSecret",
|
||||||
},
|
},
|
||||||
Data: map[string][]byte{
|
Data: map[string][]byte{
|
||||||
github.AppIDKey: []byte("123"),
|
github.KeyAppID: []byte("123"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
@ -266,94 +285,6 @@ func Test_getAuthOpts_providerAuth(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_getProxyOpts(t *testing.T) {
|
|
||||||
namespace := "default"
|
|
||||||
invalidProxy := &corev1.Secret{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "invalid-proxy",
|
|
||||||
Namespace: namespace,
|
|
||||||
},
|
|
||||||
Data: map[string][]byte{
|
|
||||||
"url": []byte("https://example.com"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
validProxy := &corev1.Secret{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "valid-proxy",
|
|
||||||
Namespace: namespace,
|
|
||||||
},
|
|
||||||
Data: map[string][]byte{
|
|
||||||
"address": []byte("https://example.com"),
|
|
||||||
"username": []byte("user"),
|
|
||||||
"password": []byte("pass"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
secretName string
|
|
||||||
want *transport.ProxyOptions
|
|
||||||
wantProxyURL *url.URL
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "non-existing secret",
|
|
||||||
secretName: "non-existing",
|
|
||||||
want: nil,
|
|
||||||
wantProxyURL: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid proxy secret",
|
|
||||||
secretName: "invalid-proxy",
|
|
||||||
want: nil,
|
|
||||||
wantProxyURL: nil,
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid proxy secret",
|
|
||||||
secretName: "valid-proxy",
|
|
||||||
want: &transport.ProxyOptions{
|
|
||||||
URL: "https://example.com",
|
|
||||||
Username: "user",
|
|
||||||
Password: "pass",
|
|
||||||
},
|
|
||||||
wantProxyURL: &url.URL{
|
|
||||||
Scheme: "https",
|
|
||||||
Host: "example.com",
|
|
||||||
User: url.UserPassword("user", "pass"),
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
g := NewWithT(t)
|
|
||||||
|
|
||||||
clientBuilder := fakeclient.NewClientBuilder().
|
|
||||||
WithScheme(scheme.Scheme).
|
|
||||||
WithObjects(invalidProxy, validProxy)
|
|
||||||
c := clientBuilder.Build()
|
|
||||||
|
|
||||||
gitRepo := &sourcev1.GitRepository{}
|
|
||||||
gitRepo.Namespace = namespace
|
|
||||||
if tt.secretName != "" {
|
|
||||||
gitRepo.Spec = sourcev1.GitRepositorySpec{
|
|
||||||
ProxySecretRef: &meta.LocalObjectReference{Name: tt.secretName},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
got, gotProxyURL, err := getProxyOpts(context.TODO(), c, gitRepo)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
g.Fail(fmt.Sprintf("unexpected error: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
g.Expect(got).To(Equal(tt.want))
|
|
||||||
g.Expect(gotProxyURL).To(Equal(tt.wantProxyURL))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_getSigningEntity(t *testing.T) {
|
func Test_getSigningEntity(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
@ -41,20 +42,42 @@ import (
|
||||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||||
|
|
||||||
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
imagev1 "github.com/fluxcd/image-automation-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/image-automation-controller/pkg/update"
|
"github.com/fluxcd/image-automation-controller/internal/update"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrInvalidSourceConfiguration is an error for invalid source configuration.
|
// ErrInvalidSourceConfiguration is an error for invalid source configuration.
|
||||||
var ErrInvalidSourceConfiguration = errors.New("invalid source configuration")
|
var ErrInvalidSourceConfiguration = errors.New("invalid source configuration")
|
||||||
|
|
||||||
|
// RemovedTemplateFieldError represents an error when a removed template field is used.
|
||||||
|
type RemovedTemplateFieldError struct {
|
||||||
|
Field string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *RemovedTemplateFieldError) Error() string {
|
||||||
|
switch e.Field {
|
||||||
|
case ".Updated":
|
||||||
|
return "template uses removed '.Updated' field. Please use '.Changed' instead. See: https://fluxcd.io/flux/components/image/imageupdateautomations/#message-template"
|
||||||
|
case ".Changed.ImageResult":
|
||||||
|
return "template uses removed '.Changed.ImageResult' field. Please use '.Changed.FileChanges' or '.Changed.Objects' instead. See: https://fluxcd.io/flux/components/image/imageupdateautomations/#message-template"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("template uses removed '%s' field. See: https://fluxcd.io/flux/components/image/imageupdateautomations/#message-template", e.Field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *RemovedTemplateFieldError) Is(target error) bool {
|
||||||
|
return errors.Is(target, ErrRemovedTemplateField)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrRemovedTemplateField is a sentinel error for removed template field usage.
|
||||||
|
var ErrRemovedTemplateField = &RemovedTemplateFieldError{}
|
||||||
|
|
||||||
const defaultMessageTemplate = `Update from image update automation`
|
const defaultMessageTemplate = `Update from image update automation`
|
||||||
|
|
||||||
// TemplateData is the type of the value given to the commit message
|
// TemplateData is the type of the value given to the commit message
|
||||||
// template.
|
// template.
|
||||||
type TemplateData struct {
|
type TemplateData struct {
|
||||||
AutomationObject types.NamespacedName
|
AutomationObject types.NamespacedName
|
||||||
Updated update.Result
|
Changed update.Result
|
||||||
Changed update.ResultV2
|
|
||||||
Values map[string]string
|
Values map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +219,19 @@ func WithCheckoutOptionShallowClone() CheckoutOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithCheckoutOptionSparseCheckoutDirectories is a CheckoutOption option to configure
|
||||||
|
// SparseCheckoutDirectories.
|
||||||
|
func WithCheckoutOptionSparseCheckoutDirectories(updatePath string) CheckoutOption {
|
||||||
|
return func(cc *repository.CloneConfig) {
|
||||||
|
cleanedPath := filepath.Clean(updatePath)
|
||||||
|
if cleanedPath == "." {
|
||||||
|
// Do not set SparseCheckoutDirectories if repository root is specified
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cc.SparseCheckoutDirectories = []string{cleanedPath}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CheckoutSource clones and checks out the source. If a push branch is
|
// CheckoutSource clones and checks out the source. If a push branch is
|
||||||
// configured that doesn't match with the checkout branch, a checkout to the
|
// configured that doesn't match with the checkout branch, a checkout to the
|
||||||
// push branch is also performed. This ensures any change and push operation
|
// push branch is also performed. This ensures any change and push operation
|
||||||
|
@ -254,7 +290,7 @@ func WithPushConfigOptions(opts map[string]string) PushConfig {
|
||||||
|
|
||||||
// CommitAndPush performs a commit in the source and pushes it to the remote
|
// CommitAndPush performs a commit in the source and pushes it to the remote
|
||||||
// repository.
|
// repository.
|
||||||
func (sm SourceManager) CommitAndPush(ctx context.Context, obj *imagev1.ImageUpdateAutomation, policyResult update.ResultV2, pushOptions ...PushConfig) (*PushResult, error) {
|
func (sm SourceManager) CommitAndPush(ctx context.Context, obj *imagev1.ImageUpdateAutomation, policyResult update.Result, pushOptions ...PushConfig) (*PushResult, error) {
|
||||||
tracelog := log.FromContext(ctx).V(logger.TraceLevel)
|
tracelog := log.FromContext(ctx).V(logger.TraceLevel)
|
||||||
|
|
||||||
// Make sure there were file changes that need to be committed.
|
// Make sure there were file changes that need to be committed.
|
||||||
|
@ -265,7 +301,6 @@ func (sm SourceManager) CommitAndPush(ctx context.Context, obj *imagev1.ImageUpd
|
||||||
// Perform a Git commit.
|
// Perform a Git commit.
|
||||||
templateValues := &TemplateData{
|
templateValues := &TemplateData{
|
||||||
AutomationObject: sm.automationObjKey,
|
AutomationObject: sm.automationObjKey,
|
||||||
Updated: policyResult.ImageResult,
|
|
||||||
Changed: policyResult,
|
Changed: policyResult,
|
||||||
Values: obj.Spec.GitSpec.Commit.MessageTemplateValues,
|
Values: obj.Spec.GitSpec.Commit.MessageTemplateValues,
|
||||||
}
|
}
|
||||||
|
@ -342,11 +377,32 @@ func templateMsg(messageTemplate string, templateValues *TemplateData) (string,
|
||||||
|
|
||||||
b := &strings.Builder{}
|
b := &strings.Builder{}
|
||||||
if err := t.Execute(b, *templateValues); err != nil {
|
if err := t.Execute(b, *templateValues); err != nil {
|
||||||
|
if removedFieldErr := checkRemovedTemplateField(err); removedFieldErr != nil {
|
||||||
|
return "", removedFieldErr
|
||||||
|
}
|
||||||
return "", fmt.Errorf("failed to run template from spec: %w", err)
|
return "", fmt.Errorf("failed to run template from spec: %w", err)
|
||||||
}
|
}
|
||||||
return b.String(), nil
|
return b.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkRemovedTemplateField checks if the template error is due to removed fields
|
||||||
|
func checkRemovedTemplateField(err error) error {
|
||||||
|
removedFieldChecks := []struct {
|
||||||
|
fieldName string
|
||||||
|
errorPattern string
|
||||||
|
}{
|
||||||
|
{".Updated", "can't evaluate field Updated in type source.TemplateData"},
|
||||||
|
{".Changed.ImageResult", "can't evaluate field ImageResult in type update.Result"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, check := range removedFieldChecks {
|
||||||
|
if strings.Contains(err.Error(), check.errorPattern) {
|
||||||
|
return &RemovedTemplateFieldError{Field: check.fieldName}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// PushResultOption allows configuring the options of PushResult.
|
// PushResultOption allows configuring the options of PushResult.
|
||||||
type PushResultOption func(*PushResult)
|
type PushResultOption func(*PushResult)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ import (
|
||||||
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
"github.com/fluxcd/pkg/git"
|
"github.com/fluxcd/pkg/git"
|
||||||
"github.com/fluxcd/pkg/gittestserver"
|
"github.com/fluxcd/pkg/gittestserver"
|
||||||
|
@ -55,8 +55,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
originRemote = "origin"
|
originRemote = "origin"
|
||||||
testCommitTemplate = `Commit summary
|
testCommitTemplateRemoved = `Commit summary
|
||||||
|
|
||||||
Automation: {{ .AutomationObject }}
|
Automation: {{ .AutomationObject }}
|
||||||
|
|
||||||
|
@ -101,11 +101,30 @@ Automation: {{ .AutomationObject }}
|
||||||
|
|
||||||
Cluster: {{ index .Values "cluster" }}
|
Cluster: {{ index .Values "cluster" }}
|
||||||
Testing: {{ .Values.testing }}
|
Testing: {{ .Values.testing }}
|
||||||
|
`
|
||||||
|
testCommitTemplateImageResult = `Commit summary
|
||||||
|
|
||||||
|
Automation: {{ .AutomationObject }}
|
||||||
|
|
||||||
|
Files:
|
||||||
|
{{ range $filename, $_ := .Changed.ImageResult.Files -}}
|
||||||
|
- {{ $filename }}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Objects:
|
||||||
|
{{ range $resource, $_ := .Changed.ImageResult.Objects -}}
|
||||||
|
- {{ $resource.Kind }} {{ $resource.Name }}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Images:
|
||||||
|
{{ range .Changed.ImageResult.Images -}}
|
||||||
|
- {{.}} ({{.Policy.Name}})
|
||||||
|
{{ end -}}
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
utilruntime.Must(imagev1_reflect.AddToScheme(scheme.Scheme))
|
utilruntime.Must(reflectorv1.AddToScheme(scheme.Scheme))
|
||||||
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
|
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
|
||||||
utilruntime.Must(imagev1.AddToScheme(scheme.Scheme))
|
utilruntime.Must(imagev1.AddToScheme(scheme.Scheme))
|
||||||
|
|
||||||
|
@ -222,13 +241,14 @@ func TestSourceManager_CheckoutSource(t *testing.T) {
|
||||||
|
|
||||||
func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
|
func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
autoGitSpec *imagev1.GitSpec
|
autoGitSpec *imagev1.GitSpec
|
||||||
gitRepoRef *sourcev1.GitRepositoryRef
|
gitRepoRef *sourcev1.GitRepositoryRef
|
||||||
shallowClone bool
|
shallowClone bool
|
||||||
lastObserved bool
|
sparseCheckoutDirectory string
|
||||||
wantErr bool
|
lastObserved bool
|
||||||
wantRef string
|
wantErr bool
|
||||||
|
wantRef string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "checkout for single branch",
|
name: "checkout for single branch",
|
||||||
|
@ -275,6 +295,42 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
wantRef: "main",
|
wantRef: "main",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "with sparse checkout",
|
||||||
|
autoGitSpec: &imagev1.GitSpec{
|
||||||
|
Push: &imagev1.PushSpec{Branch: "main"},
|
||||||
|
Checkout: &imagev1.GitCheckoutSpec{
|
||||||
|
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
|
||||||
|
wantErr: false,
|
||||||
|
wantRef: "main",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with sparse checkout for current directory",
|
||||||
|
autoGitSpec: &imagev1.GitSpec{
|
||||||
|
Push: &imagev1.PushSpec{Branch: "main"},
|
||||||
|
Checkout: &imagev1.GitCheckoutSpec{
|
||||||
|
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sparseCheckoutDirectory: "./",
|
||||||
|
wantErr: false,
|
||||||
|
wantRef: "main",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with sparse checkout for different push branch",
|
||||||
|
autoGitSpec: &imagev1.GitSpec{
|
||||||
|
Push: &imagev1.PushSpec{Branch: "foo"},
|
||||||
|
Checkout: &imagev1.GitCheckoutSpec{
|
||||||
|
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
|
||||||
|
wantErr: false,
|
||||||
|
wantRef: "foo",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "with last observed commit",
|
name: "with last observed commit",
|
||||||
autoGitSpec: &imagev1.GitSpec{
|
autoGitSpec: &imagev1.GitSpec{
|
||||||
|
@ -386,6 +442,9 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
|
||||||
if tt.shallowClone {
|
if tt.shallowClone {
|
||||||
opts = append(opts, WithCheckoutOptionShallowClone())
|
opts = append(opts, WithCheckoutOptionShallowClone())
|
||||||
}
|
}
|
||||||
|
if tt.sparseCheckoutDirectory != "" {
|
||||||
|
opts = append(opts, WithCheckoutOptionSparseCheckoutDirectories(tt.sparseCheckoutDirectory))
|
||||||
|
}
|
||||||
if tt.lastObserved {
|
if tt.lastObserved {
|
||||||
opts = append(opts, WithCheckoutOptionLastObserved(headRev))
|
opts = append(opts, WithCheckoutOptionLastObserved(headRev))
|
||||||
}
|
}
|
||||||
|
@ -429,31 +488,36 @@ func test_sourceManager_CommitAndPush(t *testing.T, proto string) {
|
||||||
checkRefSpecBranch string
|
checkRefSpecBranch string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "push to cloned branch with custom template",
|
name: "push to cloned branch with removed template field",
|
||||||
gitSpec: &imagev1.GitSpec{
|
gitSpec: &imagev1.GitSpec{
|
||||||
Push: &imagev1.PushSpec{
|
Push: &imagev1.PushSpec{
|
||||||
Branch: "main",
|
Branch: "main",
|
||||||
},
|
},
|
||||||
Commit: imagev1.CommitSpec{
|
Commit: imagev1.CommitSpec{
|
||||||
MessageTemplate: testCommitTemplate,
|
MessageTemplate: testCommitTemplateRemoved,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gitRepoReference: &sourcev1.GitRepositoryRef{
|
gitRepoReference: &sourcev1.GitRepositoryRef{
|
||||||
Branch: "main",
|
Branch: "main",
|
||||||
},
|
},
|
||||||
latestImage: "helloworld:1.0.1",
|
latestImage: "helloworld:1.0.1",
|
||||||
wantErr: false,
|
wantErr: true,
|
||||||
wantCommitMsg: `Commit summary
|
},
|
||||||
|
{
|
||||||
Automation: test-ns/test-update
|
name: "push to cloned branch with removed ImageResult field",
|
||||||
|
gitSpec: &imagev1.GitSpec{
|
||||||
Files:
|
Push: &imagev1.PushSpec{
|
||||||
- deploy.yaml
|
Branch: "main",
|
||||||
Objects:
|
},
|
||||||
- deployment test
|
Commit: imagev1.CommitSpec{
|
||||||
Images:
|
MessageTemplate: testCommitTemplateImageResult,
|
||||||
- helloworld:1.0.1 (policy1)
|
},
|
||||||
`,
|
},
|
||||||
|
gitRepoReference: &sourcev1.GitRepositoryRef{
|
||||||
|
Branch: "main",
|
||||||
|
},
|
||||||
|
latestImage: "helloworld:1.0.1",
|
||||||
|
wantErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "commit with update ResultV2 template",
|
name: "commit with update ResultV2 template",
|
||||||
|
@ -636,10 +700,10 @@ Testing: value
|
||||||
workDir := t.TempDir()
|
workDir := t.TempDir()
|
||||||
testNS := "test-ns"
|
testNS := "test-ns"
|
||||||
|
|
||||||
imgPolicy := &imagev1_reflect.ImagePolicy{}
|
imgPolicy := &reflectorv1.ImagePolicy{}
|
||||||
imgPolicy.Name = "policy1"
|
imgPolicy.Name = "policy1"
|
||||||
imgPolicy.Namespace = testNS
|
imgPolicy.Namespace = testNS
|
||||||
imgPolicy.Status = imagev1_reflect.ImagePolicyStatus{
|
imgPolicy.Status = reflectorv1.ImagePolicyStatus{
|
||||||
LatestRef: testutil.ImageToRef(tt.latestImage),
|
LatestRef: testutil.ImageToRef(tt.latestImage),
|
||||||
}
|
}
|
||||||
testObjects = append(testObjects, imgPolicy)
|
testObjects = append(testObjects, imgPolicy)
|
||||||
|
@ -725,12 +789,17 @@ Testing: value
|
||||||
_, err = sm.CheckoutSource(ctx)
|
_, err = sm.CheckoutSource(ctx)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
policies := []imagev1_reflect.ImagePolicy{*imgPolicy}
|
policies := []reflectorv1.ImagePolicy{*imgPolicy}
|
||||||
result, err := policy.ApplyPolicies(ctx, sm.workingDir, updateAuto, policies)
|
result, err := policy.ApplyPolicies(ctx, sm.workingDir, updateAuto, policies)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
pushResult, err := sm.CommitAndPush(ctx, updateAuto, result)
|
pushResult, err := sm.CommitAndPush(ctx, updateAuto, result)
|
||||||
g.Expect(err != nil).To(Equal(tt.wantErr))
|
g.Expect(err != nil).To(Equal(tt.wantErr))
|
||||||
|
if tt.wantErr {
|
||||||
|
g.Expect(pushResult).To(BeNil())
|
||||||
|
g.Expect(err).To(MatchError(ErrRemovedTemplateField))
|
||||||
|
return
|
||||||
|
}
|
||||||
if tt.noChange {
|
if tt.noChange {
|
||||||
g.Expect(pushResult).To(BeNil())
|
g.Expect(pushResult).To(BeNil())
|
||||||
return
|
return
|
||||||
|
@ -861,10 +930,10 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
|
||||||
// Create ImagePolicy, GitRepository and ImageUpdateAutomation objects.
|
// Create ImagePolicy, GitRepository and ImageUpdateAutomation objects.
|
||||||
latestImage := "helloworld:1.0.1"
|
latestImage := "helloworld:1.0.1"
|
||||||
|
|
||||||
imgPolicy := &imagev1_reflect.ImagePolicy{}
|
imgPolicy := &reflectorv1.ImagePolicy{}
|
||||||
imgPolicy.Name = "policy1"
|
imgPolicy.Name = "policy1"
|
||||||
imgPolicy.Namespace = testNS
|
imgPolicy.Namespace = testNS
|
||||||
imgPolicy.Status = imagev1_reflect.ImagePolicyStatus{
|
imgPolicy.Status = reflectorv1.ImagePolicyStatus{
|
||||||
LatestRef: testutil.ImageToRef(latestImage),
|
LatestRef: testutil.ImageToRef(latestImage),
|
||||||
}
|
}
|
||||||
testObjects = append(testObjects, imgPolicy)
|
testObjects = append(testObjects, imgPolicy)
|
||||||
|
@ -934,7 +1003,7 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
|
||||||
checkoutBranchHead, err := testutil.HeadFromBranch(localRepo, branch)
|
checkoutBranchHead, err := testutil.HeadFromBranch(localRepo, branch)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
policies := []imagev1_reflect.ImagePolicy{*imgPolicy}
|
policies := []reflectorv1.ImagePolicy{*imgPolicy}
|
||||||
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
|
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
|
||||||
|
|
||||||
// Pull the new changes to the local repo.
|
// Pull the new changes to the local repo.
|
||||||
|
@ -969,7 +1038,7 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
|
||||||
imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage)
|
imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage)
|
||||||
g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed())
|
g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed())
|
||||||
|
|
||||||
policies = []imagev1_reflect.ImagePolicy{*imgPolicy}
|
policies = []reflectorv1.ImagePolicy{*imgPolicy}
|
||||||
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
|
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
|
||||||
|
|
||||||
// Pull the new changes to the local repo.
|
// Pull the new changes to the local repo.
|
||||||
|
@ -1017,7 +1086,7 @@ func test_pushBranchUpdateScenarios(t *testing.T, proto string, srcOpts []Source
|
||||||
imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage)
|
imgPolicy.Status.LatestRef = testutil.ImageToRef(latestImage)
|
||||||
g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed())
|
g.Expect(kClient.Update(ctx, imgPolicy)).To(Succeed())
|
||||||
|
|
||||||
policies = []imagev1_reflect.ImagePolicy{*imgPolicy}
|
policies = []reflectorv1.ImagePolicy{*imgPolicy}
|
||||||
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
|
checkoutAndUpdate(ctx, g, kClient, updateAuto, policies, srcOpts, checkoutOpts, pushCfg)
|
||||||
|
|
||||||
// Pull the new changes to the local repo.
|
// Pull the new changes to the local repo.
|
||||||
|
@ -1107,7 +1176,7 @@ Update from image update automation`, "foo", testBranch),
|
||||||
// checkoutAndUpdate performs source checkout, update and push for the given
|
// checkoutAndUpdate performs source checkout, update and push for the given
|
||||||
// arguments.
|
// arguments.
|
||||||
func checkoutAndUpdate(ctx context.Context, g *WithT, kClient client.Client,
|
func checkoutAndUpdate(ctx context.Context, g *WithT, kClient client.Client,
|
||||||
updateAuto *imagev1.ImageUpdateAutomation, policies []imagev1_reflect.ImagePolicy,
|
updateAuto *imagev1.ImageUpdateAutomation, policies []reflectorv1.ImagePolicy,
|
||||||
srcOpts []SourceOption, checkoutOpts []CheckoutOption, pushCfg []PushConfig) {
|
srcOpts []SourceOption, checkoutOpts []CheckoutOption, pushCfg []PushConfig) {
|
||||||
g.THelper()
|
g.THelper()
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package test
|
package testutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
@ -24,8 +24,10 @@ import (
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO rewrite this as just doing the diff, so I can test that it
|
// ExpectMatchingDirectories compares two directories, recursively, and
|
||||||
// fails at the right times too.
|
// expects them to match. It will fail if there are files that are
|
||||||
|
// present in one directory but not the other, or if files that are
|
||||||
|
// present in both directories have different contents.
|
||||||
func ExpectMatchingDirectories(g *WithT, actualRoot, expectedRoot string) {
|
func ExpectMatchingDirectories(g *WithT, actualRoot, expectedRoot string) {
|
||||||
g.Expect(actualRoot).To(BeADirectory())
|
g.Expect(actualRoot).To(BeADirectory())
|
||||||
g.Expect(expectedRoot).To(BeADirectory())
|
g.Expect(expectedRoot).To(BeADirectory())
|
||||||
|
@ -43,29 +45,28 @@ type Diff interface {
|
||||||
FailedExpectation(g *WithT)
|
FailedExpectation(g *WithT)
|
||||||
}
|
}
|
||||||
|
|
||||||
type contentdiff struct {
|
type contentDiff struct {
|
||||||
path, actual, expected string
|
path, actual, expected string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d contentdiff) Path() string {
|
func (d contentDiff) Path() string {
|
||||||
return d.path
|
return d.path
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run an expectation that will fail, giving an appropriate error
|
func (d contentDiff) FailedExpectation(g *WithT) {
|
||||||
func (d contentdiff) FailedExpectation(g *WithT) {
|
|
||||||
g.Expect(d.actual).To(Equal(d.expected))
|
g.Expect(d.actual).To(Equal(d.expected))
|
||||||
}
|
}
|
||||||
|
|
||||||
type dirfile struct {
|
type dirFile struct {
|
||||||
abspath, path string
|
abspath, path string
|
||||||
expectedRegularFile bool
|
expectedRegularFile bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d dirfile) Path() string {
|
func (d dirFile) Path() string {
|
||||||
return d.path
|
return d.path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d dirfile) FailedExpectation(g *WithT) {
|
func (d dirFile) FailedExpectation(g *WithT) {
|
||||||
if d.expectedRegularFile {
|
if d.expectedRegularFile {
|
||||||
g.Expect(d.path).To(BeARegularFile())
|
g.Expect(d.path).To(BeARegularFile())
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,7 +126,7 @@ func DiffDirectories(actual, expected string) (actualonly []string, expectedonly
|
||||||
case actualInfo.IsDir() && expectedInfo.IsDir():
|
case actualInfo.IsDir() && expectedInfo.IsDir():
|
||||||
return nil // i.e., keep recursing
|
return nil // i.e., keep recursing
|
||||||
case actualInfo.IsDir() || expectedInfo.IsDir():
|
case actualInfo.IsDir() || expectedInfo.IsDir():
|
||||||
different = append(different, dirfile{path: relPath, abspath: actualPath, expectedRegularFile: actualInfo.IsDir()})
|
different = append(different, dirFile{path: relPath, abspath: actualPath, expectedRegularFile: actualInfo.IsDir()})
|
||||||
if expectedInfo.IsDir() {
|
if expectedInfo.IsDir() {
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
}
|
}
|
||||||
|
@ -143,7 +144,7 @@ func DiffDirectories(actual, expected string) (actualonly []string, expectedonly
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if string(actualBytes) != string(expectedBytes) {
|
if string(actualBytes) != string(expectedBytes) {
|
||||||
different = append(different, contentdiff{path: relPath, actual: string(actualBytes), expected: string(expectedBytes)})
|
different = append(different, contentDiff{path: relPath, actual: string(actualBytes), expected: string(expectedBytes)})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package test
|
package testutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
|
@ -44,8 +44,9 @@ import (
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/gittestserver"
|
"github.com/fluxcd/pkg/gittestserver"
|
||||||
|
|
||||||
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
|
|
||||||
"github.com/fluxcd/image-automation-controller/internal/constants"
|
"github.com/fluxcd/image-automation-controller/internal/constants"
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -459,7 +460,7 @@ func GetSigningKeyPair(g *WithT, passphrase string) (*openpgp.Entity, []byte) {
|
||||||
return pgpEntity, b.Bytes()
|
return pgpEntity, b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ImageToRef(image string) *imagev1_reflect.ImageRef {
|
func ImageToRef(image string) *reflectorv1.ImageRef {
|
||||||
var digest string
|
var digest string
|
||||||
|
|
||||||
if idx := strings.LastIndex(image, "@"); idx != -1 {
|
if idx := strings.LastIndex(image, "@"); idx != -1 {
|
||||||
|
@ -472,7 +473,7 @@ func ImageToRef(image string) *imagev1_reflect.ImageRef {
|
||||||
image, tag = image[:idx], image[idx+1:]
|
image, tag = image[:idx], image[idx+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
return &imagev1_reflect.ImageRef{
|
return &reflectorv1.ImageRef{
|
||||||
Name: image,
|
Name: image,
|
||||||
Tag: tag,
|
Tag: tag,
|
||||||
Digest: digest,
|
Digest: digest,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020, 2021 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -28,7 +28,7 @@ import (
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ScreeningReader is a kio.Reader that includes only files that are
|
// ScreeningLocalReader is a kio.Reader that includes only files that are
|
||||||
// pertinent to automation. In practice this means looking for a
|
// pertinent to automation. In practice this means looking for a
|
||||||
// particular token in each file, and ignoring those files without the
|
// particular token in each file, and ignoring those files without the
|
||||||
// token. This avoids most problematic cases -- e.g., templates in a
|
// token. This avoids most problematic cases -- e.g., templates in a
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020, 2021 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020, 2021 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package update
|
package update
|
||||||
|
|
||||||
import (
|
import (
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package update
|
package update
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -55,54 +71,10 @@ type ObjectIdentifier struct {
|
||||||
yaml.ResourceIdentifier
|
yaml.ResourceIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// Result reports the outcome of an automated update. It has a nested
|
// Result contains the file changes made during the update. It contains
|
||||||
// structure file->objects->images. Different projections (e.g., all
|
// details about the exact changes made to the files and the objects in them.
|
||||||
// the images, regardless of object) are available via methods.
|
// It has a nested structure file->objects->changes.
|
||||||
type Result struct {
|
type Result struct {
|
||||||
Files map[string]FileResult
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileResult gives the updates in a particular file.
|
|
||||||
type FileResult struct {
|
|
||||||
Objects map[ObjectIdentifier][]ImageRef
|
|
||||||
}
|
|
||||||
|
|
||||||
// Images returns all the images that were involved in at least one
|
|
||||||
// update.
|
|
||||||
func (r Result) Images() []ImageRef {
|
|
||||||
seen := make(map[ImageRef]struct{})
|
|
||||||
var result []ImageRef
|
|
||||||
for _, file := range r.Files {
|
|
||||||
for _, images := range file.Objects {
|
|
||||||
for _, ref := range images {
|
|
||||||
if _, ok := seen[ref]; !ok {
|
|
||||||
seen[ref] = struct{}{}
|
|
||||||
result = append(result, ref)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// Objects returns a map of all the objects against the images updated
|
|
||||||
// within, regardless of which file they appear in.
|
|
||||||
func (r Result) Objects() map[ObjectIdentifier][]ImageRef {
|
|
||||||
result := make(map[ObjectIdentifier][]ImageRef)
|
|
||||||
for _, file := range r.Files {
|
|
||||||
for res, refs := range file.Objects {
|
|
||||||
result[res] = append(result[res], refs...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResultV2 contains Result of update and also the file changes made during the
|
|
||||||
// update. This extends the Result to include details about the exact changes
|
|
||||||
// made to the files and the objects in them. It has a nested structure
|
|
||||||
// file->objects->changes.
|
|
||||||
type ResultV2 struct {
|
|
||||||
ImageResult Result
|
|
||||||
FileChanges map[string]ObjectChanges
|
FileChanges map[string]ObjectChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +89,9 @@ type Change struct {
|
||||||
Setter string
|
Setter string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddChange adds changes to Resultv2 for a given file, object and changes
|
// AddChange adds changes to Result for a given file, object and changes
|
||||||
// associated with it.
|
// associated with it.
|
||||||
func (r *ResultV2) AddChange(file string, objectID ObjectIdentifier, changes ...Change) {
|
func (r *Result) AddChange(file string, objectID ObjectIdentifier, changes ...Change) {
|
||||||
if r.FileChanges == nil {
|
if r.FileChanges == nil {
|
||||||
r.FileChanges = map[string]ObjectChanges{}
|
r.FileChanges = map[string]ObjectChanges{}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +105,7 @@ func (r *ResultV2) AddChange(file string, objectID ObjectIdentifier, changes ...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changes returns all the changes that were made in at least one update.
|
// Changes returns all the changes that were made in at least one update.
|
||||||
func (r ResultV2) Changes() []Change {
|
func (r Result) Changes() []Change {
|
||||||
seen := make(map[Change]struct{})
|
seen := make(map[Change]struct{})
|
||||||
var result []Change
|
var result []Change
|
||||||
for _, objChanges := range r.FileChanges {
|
for _, objChanges := range r.FileChanges {
|
||||||
|
@ -150,7 +122,7 @@ func (r ResultV2) Changes() []Change {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objects returns ObjectChanges, regardless of which file they appear in.
|
// Objects returns ObjectChanges, regardless of which file they appear in.
|
||||||
func (r ResultV2) Objects() ObjectChanges {
|
func (r Result) Objects() ObjectChanges {
|
||||||
result := make(ObjectChanges)
|
result := make(ObjectChanges)
|
||||||
for _, objChanges := range r.FileChanges {
|
for _, objChanges := range r.FileChanges {
|
||||||
for obj, change := range objChanges {
|
for obj, change := range objChanges {
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package update
|
package update
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -42,7 +58,7 @@ func TestMustRef(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateResults(t *testing.T) {
|
func TestResult(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
var result Result
|
var result Result
|
||||||
|
@ -55,57 +71,6 @@ func TestUpdateResults(t *testing.T) {
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Result{
|
|
||||||
Files: map[string]FileResult{
|
|
||||||
"foo.yaml": {
|
|
||||||
Objects: map[ObjectIdentifier][]ImageRef{
|
|
||||||
objectNames[0]: {
|
|
||||||
mustRef("image:v1.0"),
|
|
||||||
mustRef("other:v2.0"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"bar.yaml": {
|
|
||||||
Objects: map[ObjectIdentifier][]ImageRef{
|
|
||||||
objectNames[1]: {
|
|
||||||
mustRef("image:v1.0"),
|
|
||||||
mustRef("other:v2.0"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g.Expect(result.Images()).To(Equal([]ImageRef{
|
|
||||||
mustRef("image:v1.0"),
|
|
||||||
mustRef("other:v2.0"),
|
|
||||||
}))
|
|
||||||
|
|
||||||
g.Expect(result.Objects()).To(Equal(map[ObjectIdentifier][]ImageRef{
|
|
||||||
objectNames[0]: {
|
|
||||||
mustRef("image:v1.0"),
|
|
||||||
mustRef("other:v2.0"),
|
|
||||||
},
|
|
||||||
objectNames[1]: {
|
|
||||||
mustRef("image:v1.0"),
|
|
||||||
mustRef("other:v2.0"),
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResultV2(t *testing.T) {
|
|
||||||
g := NewWithT(t)
|
|
||||||
|
|
||||||
var result ResultV2
|
|
||||||
objectNames := []ObjectIdentifier{
|
|
||||||
{yaml.ResourceIdentifier{
|
|
||||||
NameMeta: yaml.NameMeta{Namespace: "ns", Name: "foo"},
|
|
||||||
}},
|
|
||||||
{yaml.ResourceIdentifier{
|
|
||||||
NameMeta: yaml.NameMeta{Namespace: "ns", Name: "bar"},
|
|
||||||
}},
|
|
||||||
}
|
|
||||||
|
|
||||||
result.AddChange("foo.yaml", objectNames[0], Change{
|
result.AddChange("foo.yaml", objectNames[0], Change{
|
||||||
OldValue: "aaa",
|
OldValue: "aaa",
|
||||||
NewValue: "bbb",
|
NewValue: "bbb",
|
||||||
|
@ -117,7 +82,7 @@ func TestResultV2(t *testing.T) {
|
||||||
Setter: "foo-ns:policy",
|
Setter: "foo-ns:policy",
|
||||||
})
|
})
|
||||||
|
|
||||||
result = ResultV2{
|
result = Result{
|
||||||
FileChanges: map[string]ObjectChanges{
|
FileChanges: map[string]ObjectChanges{
|
||||||
"foo.yaml": {
|
"foo.yaml": {
|
||||||
objectNames[0]: []Change{
|
objectNames[0]: []Change{
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020, 2021 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -30,12 +30,13 @@ import (
|
||||||
"sigs.k8s.io/kustomize/kyaml/sets"
|
"sigs.k8s.io/kustomize/kyaml/sets"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
|
|
||||||
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
|
|
||||||
"github.com/fluxcd/image-automation-controller/internal/constants"
|
"github.com/fluxcd/image-automation-controller/internal/constants"
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// This is preserved from setters2
|
// K8sCliExtensionKey is preserved from setters2
|
||||||
K8sCliExtensionKey = "x-k8s-cli"
|
K8sCliExtensionKey = "x-k8s-cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,17 +50,9 @@ func init() {
|
||||||
|
|
||||||
// UpdateWithSetters takes all YAML files from `inpath`, updates any
|
// UpdateWithSetters takes all YAML files from `inpath`, updates any
|
||||||
// that contain an "in scope" image policy marker, and writes files it
|
// that contain an "in scope" image policy marker, and writes files it
|
||||||
// updated (and only those files) back to `outpath`.
|
|
||||||
func UpdateWithSetters(tracelog logr.Logger, inpath, outpath string, policies []imagev1_reflect.ImagePolicy) (Result, error) {
|
|
||||||
result, err := UpdateV2WithSetters(tracelog, inpath, outpath, policies)
|
|
||||||
return result.ImageResult, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateV2WithSetters takes all YAML files from `inpath`, updates any
|
|
||||||
// that contain an "in scope" image policy marker, and writes files it
|
|
||||||
// updated (and only those files) back to `outpath`. It also returns the result
|
// updated (and only those files) back to `outpath`. It also returns the result
|
||||||
// of the changes it made as ResultV2.
|
// of the changes it made as Result.
|
||||||
func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies []imagev1_reflect.ImagePolicy) (ResultV2, error) {
|
func UpdateWithSetters(tracelog logr.Logger, inpath, outpath string, policies []reflectorv1.ImagePolicy) (Result, error) {
|
||||||
// the OpenAPI schema is a package variable in kyaml/openapi. In
|
// the OpenAPI schema is a package variable in kyaml/openapi. In
|
||||||
// lieu of being able to isolate invocations (per
|
// lieu of being able to isolate invocations (per
|
||||||
// https://github.com/kubernetes-sigs/kustomize/issues/3058), I
|
// https://github.com/kubernetes-sigs/kustomize/issues/3058), I
|
||||||
|
@ -99,11 +92,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
|
||||||
|
|
||||||
// collect setter defs and setters by going through all the image
|
// collect setter defs and setters by going through all the image
|
||||||
// policies available.
|
// policies available.
|
||||||
result := Result{
|
var result Result
|
||||||
Files: make(map[string]FileResult),
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultV2 ResultV2
|
|
||||||
|
|
||||||
// Compilng the result needs the file, the image ref used, and the
|
// Compilng the result needs the file, the image ref used, and the
|
||||||
// object. Each setter will supply its own name to its callback,
|
// object. Each setter will supply its own name to its callback,
|
||||||
|
@ -112,7 +101,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
|
||||||
// iterates.
|
// iterates.
|
||||||
imageRefs := make(map[string]imageRef)
|
imageRefs := make(map[string]imageRef)
|
||||||
setAllCallback := func(file, setterName string, node *yaml.RNode, old, new string) {
|
setAllCallback := func(file, setterName string, node *yaml.RNode, old, new string) {
|
||||||
ref, ok := imageRefs[setterName]
|
_, ok := imageRefs[setterName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -130,23 +119,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
|
||||||
Setter: setterName,
|
Setter: setterName,
|
||||||
}
|
}
|
||||||
// Append the change for the file and identifier.
|
// Append the change for the file and identifier.
|
||||||
resultV2.AddChange(file, oid, ch)
|
result.AddChange(file, oid, ch)
|
||||||
|
|
||||||
fileres, ok := result.Files[file]
|
|
||||||
if !ok {
|
|
||||||
fileres = FileResult{
|
|
||||||
Objects: make(map[ObjectIdentifier][]ImageRef),
|
|
||||||
}
|
|
||||||
result.Files[file] = fileres
|
|
||||||
}
|
|
||||||
objres := fileres.Objects[oid]
|
|
||||||
for _, n := range objres {
|
|
||||||
if n == ref {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
objres = append(objres, ref)
|
|
||||||
fileres.Objects[oid] = objres
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defs := map[string]spec.Schema{}
|
defs := map[string]spec.Schema{}
|
||||||
|
@ -163,7 +136,7 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
|
||||||
image := policy.Status.LatestRef.String()
|
image := policy.Status.LatestRef.String()
|
||||||
r, err := name.ParseReference(image, name.WeakValidation)
|
r, err := name.ParseReference(image, name.WeakValidation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ResultV2{}, fmt.Errorf("encountered invalid image ref %q: %w", image, err)
|
return Result{}, fmt.Errorf("encountered invalid image ref %q: %w", image, err)
|
||||||
}
|
}
|
||||||
ref := imageRef{
|
ref := imageRef{
|
||||||
Reference: r,
|
Reference: r,
|
||||||
|
@ -221,12 +194,10 @@ func UpdateV2WithSetters(tracelog logr.Logger, inpath, outpath string, policies
|
||||||
// go!
|
// go!
|
||||||
err := pipeline.Execute()
|
err := pipeline.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ResultV2{}, err
|
return Result{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine the results.
|
return result, nil
|
||||||
resultV2.ImageResult = result
|
|
||||||
return resultV2, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setAll returns a kio.Filter using the supplied SetAllCallback
|
// setAll returns a kio.Filter using the supplied SetAllCallback
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020, 2021 The Flux authors
|
Copyright 2025 The Flux authors
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -20,27 +20,25 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
|
|
||||||
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
|
|
||||||
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
"github.com/fluxcd/image-automation-controller/internal/testutil"
|
||||||
"github.com/fluxcd/image-automation-controller/pkg/test"
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUpdateWithSetters(t *testing.T) {
|
func TestUpdateWithSetters(t *testing.T) {
|
||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
|
|
||||||
policies := []imagev1_reflect.ImagePolicy{
|
policies := []reflectorv1.ImagePolicy{
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Namespace: "automation-ns",
|
Namespace: "automation-ns",
|
||||||
Name: "policy",
|
Name: "policy",
|
||||||
},
|
},
|
||||||
Status: imagev1_reflect.ImagePolicyStatus{
|
Status: reflectorv1.ImagePolicyStatus{
|
||||||
LatestRef: testutil.ImageToRef("index.repo.fake/updated:v1.0.1"),
|
LatestRef: testutil.ImageToRef("index.repo.fake/updated:v1.0.1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -49,7 +47,7 @@ func TestUpdateWithSetters(t *testing.T) {
|
||||||
Namespace: "automation-ns",
|
Namespace: "automation-ns",
|
||||||
Name: "unchanged",
|
Name: "unchanged",
|
||||||
},
|
},
|
||||||
Status: imagev1_reflect.ImagePolicyStatus{
|
Status: reflectorv1.ImagePolicyStatus{
|
||||||
LatestRef: testutil.ImageToRef("image:v1.0.0"),
|
LatestRef: testutil.ImageToRef("image:v1.0.0"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -58,16 +56,17 @@ func TestUpdateWithSetters(t *testing.T) {
|
||||||
Namespace: "automation-ns",
|
Namespace: "automation-ns",
|
||||||
Name: "policy-with-digest",
|
Name: "policy-with-digest",
|
||||||
},
|
},
|
||||||
Status: imagev1_reflect.ImagePolicyStatus{
|
Status: reflectorv1.ImagePolicyStatus{
|
||||||
LatestRef: testutil.ImageToRef("image:v1.0.0@sha256:6745aaad46d795c9836632e1fb62f24b7e7f4c843144da8e47a5465c411a14be"),
|
LatestRef: testutil.ImageToRef("image:v1.0.0@sha256:6745aaad46d795c9836632e1fb62f24b7e7f4c843144da8e47a5465c411a14be"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test Result.
|
||||||
tmp := t.TempDir()
|
tmp := t.TempDir()
|
||||||
result, err := UpdateWithSetters(logr.Discard(), "testdata/setters/original", tmp, policies)
|
result, err := UpdateWithSetters(logr.Discard(), "testdata/setters/original", tmp, policies)
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
g.Expect(err).ToNot(HaveOccurred())
|
||||||
test.ExpectMatchingDirectories(g, tmp, "testdata/setters/expected")
|
testutil.ExpectMatchingDirectories(g, tmp, "testdata/setters/expected")
|
||||||
|
|
||||||
kustomizeResourceID := ObjectIdentifier{yaml.ResourceIdentifier{
|
kustomizeResourceID := ObjectIdentifier{yaml.ResourceIdentifier{
|
||||||
TypeMeta: yaml.TypeMeta{
|
TypeMeta: yaml.TypeMeta{
|
||||||
|
@ -86,55 +85,7 @@ func TestUpdateWithSetters(t *testing.T) {
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
r, _ := name.ParseReference("index.repo.fake/updated:v1.0.1")
|
|
||||||
expectedImageRef := imageRef{r, types.NamespacedName{
|
|
||||||
Name: "policy",
|
|
||||||
Namespace: "automation-ns",
|
|
||||||
}}
|
|
||||||
|
|
||||||
r, _ = name.ParseReference("image:v1.0.0@sha256:6745aaad46d795c9836632e1fb62f24b7e7f4c843144da8e47a5465c411a14be")
|
|
||||||
expectedImageRefDigest := imageRef{r, types.NamespacedName{
|
|
||||||
Name: "policy-with-digest",
|
|
||||||
Namespace: "automation-ns",
|
|
||||||
}}
|
|
||||||
|
|
||||||
expectedResult := Result{
|
expectedResult := Result{
|
||||||
Files: map[string]FileResult{
|
|
||||||
"kustomization.yml": {
|
|
||||||
Objects: map[ObjectIdentifier][]ImageRef{
|
|
||||||
kustomizeResourceID: {
|
|
||||||
expectedImageRef,
|
|
||||||
expectedImageRefDigest,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"Kustomization": {
|
|
||||||
Objects: map[ObjectIdentifier][]ImageRef{
|
|
||||||
kustomizeResourceID: {
|
|
||||||
expectedImageRef,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"marked.yaml": {
|
|
||||||
Objects: map[ObjectIdentifier][]ImageRef{
|
|
||||||
markedResourceID: {
|
|
||||||
expectedImageRef,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
g.Expect(result).To(Equal(expectedResult))
|
|
||||||
|
|
||||||
// Test ResultV2.
|
|
||||||
tmp2 := t.TempDir()
|
|
||||||
resultV2, err := UpdateV2WithSetters(logr.Discard(), "testdata/setters/original", tmp2, policies)
|
|
||||||
g.Expect(err).ToNot(HaveOccurred())
|
|
||||||
test.ExpectMatchingDirectories(g, tmp2, "testdata/setters/expected")
|
|
||||||
|
|
||||||
expectedResultV2 := ResultV2{
|
|
||||||
ImageResult: expectedResult,
|
|
||||||
FileChanges: map[string]ObjectChanges{
|
FileChanges: map[string]ObjectChanges{
|
||||||
"kustomization.yml": {
|
"kustomization.yml": {
|
||||||
kustomizeResourceID: []Change{
|
kustomizeResourceID: []Change{
|
||||||
|
@ -186,5 +137,5 @@ func TestUpdateWithSetters(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
g.Expect(resultV2).To(Equal(expectedResultV2))
|
g.Expect(result).To(Equal(expectedResult))
|
||||||
}
|
}
|
16
main.go
16
main.go
|
@ -34,7 +34,7 @@ import (
|
||||||
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
|
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
|
||||||
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
||||||
|
|
||||||
imagev1_reflect "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
reflectorv1 "github.com/fluxcd/image-reflector-controller/api/v1beta2"
|
||||||
"github.com/fluxcd/pkg/auth"
|
"github.com/fluxcd/pkg/auth"
|
||||||
cache "github.com/fluxcd/pkg/cache"
|
cache "github.com/fluxcd/pkg/cache"
|
||||||
"github.com/fluxcd/pkg/runtime/acl"
|
"github.com/fluxcd/pkg/runtime/acl"
|
||||||
|
@ -69,7 +69,7 @@ var (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||||
utilruntime.Must(imagev1_reflect.AddToScheme(scheme))
|
utilruntime.Must(reflectorv1.AddToScheme(scheme))
|
||||||
utilruntime.Must(sourcev1.AddToScheme(scheme))
|
utilruntime.Must(sourcev1.AddToScheme(scheme))
|
||||||
utilruntime.Must(imagev1.AddToScheme(scheme))
|
utilruntime.Must(imagev1.AddToScheme(scheme))
|
||||||
// +kubebuilder:scaffold:scheme
|
// +kubebuilder:scaffold:scheme
|
||||||
|
@ -93,12 +93,15 @@ func main() {
|
||||||
watchOptions helper.WatchOptions
|
watchOptions helper.WatchOptions
|
||||||
concurrent int
|
concurrent int
|
||||||
tokenCacheOptions cache.TokenFlags
|
tokenCacheOptions cache.TokenFlags
|
||||||
|
defaultServiceAccount string
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
|
||||||
flag.StringVar(&eventsAddr, "events-addr", "", "The address of the events receiver.")
|
flag.StringVar(&eventsAddr, "events-addr", "", "The address of the events receiver.")
|
||||||
flag.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.")
|
flag.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.")
|
||||||
flag.IntVar(&concurrent, "concurrent", 4, "The number of concurrent resource reconciles.")
|
flag.IntVar(&concurrent, "concurrent", 4, "The number of concurrent resource reconciles.")
|
||||||
|
flag.StringVar(&defaultServiceAccount, auth.ControllerFlagDefaultServiceAccount,
|
||||||
|
"", "Default service account to use for workload identity when not specified in resources.")
|
||||||
flag.StringSliceVar(&git.KexAlgos, "ssh-kex-algos", []string{},
|
flag.StringSliceVar(&git.KexAlgos, "ssh-kex-algos", []string{},
|
||||||
"The list of key exchange algorithms to use for ssh connections, arranged from most preferred to the least.")
|
"The list of key exchange algorithms to use for ssh connections, arranged from most preferred to the least.")
|
||||||
flag.StringSliceVar(&git.HostKeyAlgos, "ssh-hostkey-algos", []string{},
|
flag.StringSliceVar(&git.HostKeyAlgos, "ssh-hostkey-algos", []string{},
|
||||||
|
@ -132,6 +135,15 @@ func main() {
|
||||||
auth.EnableObjectLevelWorkloadIdentity()
|
auth.EnableObjectLevelWorkloadIdentity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if defaultServiceAccount != "" {
|
||||||
|
auth.SetDefaultServiceAccount(defaultServiceAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
if auth.InconsistentObjectLevelConfiguration() {
|
||||||
|
setupLog.Error(auth.ErrInconsistentObjectLevelConfiguration, "invalid configuration")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
watchNamespace := ""
|
watchNamespace := ""
|
||||||
if !watchOptions.AllNamespaces {
|
if !watchOptions.AllNamespaces {
|
||||||
watchNamespace = os.Getenv("RUNTIME_NAMESPACE")
|
watchNamespace = os.Getenv("RUNTIME_NAMESPACE")
|
||||||
|
|
Loading…
Reference in New Issue