Compare commits
No commits in common. "main" and "v0.12.2" have entirely different histories.
|
@ -1,39 +0,0 @@
|
|||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
labels: ["dependencies"]
|
||||
schedule:
|
||||
interval: "daily"
|
||||
groups:
|
||||
go-deps:
|
||||
patterns:
|
||||
- "*"
|
||||
allow:
|
||||
- dependency-type: "direct"
|
||||
ignore:
|
||||
# Kubernetes deps are updated by fluxcd/pkg/runtime
|
||||
- dependency-name: "k8s.io/*"
|
||||
- dependency-name: "sigs.k8s.io/*"
|
||||
- dependency-name: "github.com/go-logr/*"
|
||||
# jsondiff is updated by fluxcd/pkg/ssa
|
||||
- dependency-name: "github.com/wI2L/jsondiff"
|
||||
# OCI deps are updated by fluxcd/pkg/oci
|
||||
- dependency-name: "github.com/google/go-containerregistry*"
|
||||
- dependency-name: "github.com/opencontainers/*"
|
||||
# Helm deps are updated by fluxcd/pkg/helmtestserver
|
||||
- dependency-name: "helm.sh/helm/*"
|
||||
- dependency-name: "github.com/Masterminds/semver/*"
|
||||
# Flux APIs are updated at release time
|
||||
- dependency-name: "github.com/fluxcd/helm-controller/api"
|
||||
- dependency-name: "github.com/fluxcd/source-controller/api"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
labels: ["area/ci", "dependencies"]
|
||||
groups:
|
||||
ci:
|
||||
patterns:
|
||||
- "*"
|
||||
schedule:
|
||||
interval: "monthly"
|
|
@ -1,27 +0,0 @@
|
|||
# Configuration file to declaratively configure labels
|
||||
# Ref: https://github.com/EndBug/label-sync#Config-files
|
||||
|
||||
- name: area/drift
|
||||
description: Drift detection/correction related issues and pull requests
|
||||
color: '#ff5c00'
|
||||
- name: area/helm
|
||||
description: Helm related issues and pull requests
|
||||
color: '#1673b6'
|
||||
- name: area/kustomize
|
||||
description: Kustomize (post-rendering) related issues and pull requests
|
||||
color: '#00e54d'
|
||||
- name: area/oci
|
||||
description: OCI related issues and pull requests
|
||||
color: '#c739ff'
|
||||
- name: backport:release/v1.0.x
|
||||
description: To be backported to release/v1.0.x
|
||||
color: '#ffd700'
|
||||
- name: backport:release/v1.1.x
|
||||
description: To be backported to release/v1.1.x
|
||||
color: '#ffd700'
|
||||
- name: backport:release/v1.2.x
|
||||
description: To be backported to release/v1.2.x
|
||||
color: '#ffd700'
|
||||
- name: backport:release/v1.3.x
|
||||
description: To be backported to release/v1.3.x
|
||||
color: '#ffd700'
|
|
@ -1,34 +0,0 @@
|
|||
name: backport
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [closed, labeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
pull-request:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Create backport PRs
|
||||
uses: korthout/backport-action@0193454f0c5947491d348f33a275c119f30eb736 # v3.2.1
|
||||
# xref: https://github.com/korthout/backport-action#inputs
|
||||
with:
|
||||
# Use token to allow workflows to be triggered for the created PR
|
||||
github_token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
# Match labels with a pattern `backport:<target-branch>`
|
||||
label_pattern: '^backport:([^ ]+)$'
|
||||
# A bit shorter pull-request title than the default
|
||||
pull_title: '[${target_branch}] ${pull_title}'
|
||||
# Simpler PR description than default
|
||||
pull_description: |-
|
||||
Automated backport to `${target_branch}`, triggered by a label in #${pull_number}.
|
|
@ -1,25 +0,0 @@
|
|||
name: fuzz
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/**"
|
||||
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
|
||||
jobs:
|
||||
smoketest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: 1.24.x
|
||||
cache-dependency-path: |
|
||||
**/go.sum
|
||||
**/go.mod
|
||||
- name: Smoke test Fuzzers
|
||||
run: make fuzz-smoketest
|
|
@ -1,30 +1,36 @@
|
|||
name: e2e
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/**"
|
||||
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
|
||||
- main
|
||||
- "feature/**"
|
||||
jobs:
|
||||
kind:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: all
|
||||
- name: Setup Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
- name: Restore Go cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
uses: actions/cache@v2
|
||||
id: cache
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
|
@ -32,24 +38,26 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-buildx-ghcache-
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.24.x
|
||||
cache-dependency-path: |
|
||||
**/go.sum
|
||||
**/go.mod
|
||||
go-version: 1.16.x
|
||||
- name: Setup Kubernetes
|
||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
||||
uses: engineerd/setup-kind@v0.5.0
|
||||
with:
|
||||
version: v0.20.0
|
||||
cluster_name: kind
|
||||
node_image: kindest/node:v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72
|
||||
version: v0.11.1
|
||||
image: kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6
|
||||
- name: Setup Helm
|
||||
uses: fluxcd/pkg/actions/helm@main
|
||||
- name: Setup Kustomize
|
||||
uses: fluxcd/pkg/actions/kustomize@main
|
||||
- name: Setup Kubebuilder
|
||||
uses: fluxcd/pkg/actions/kubebuilder@main
|
||||
- name: Setup Kubectl
|
||||
uses: fluxcd/pkg/actions/kubectl@main
|
||||
- name: Run tests
|
||||
run: make test
|
||||
env:
|
||||
KUBEBUILDER_ASSETS: ${{ github.workspace }}/kubebuilder/bin
|
||||
- name: Check if working tree is dirty
|
||||
run: |
|
||||
if [[ $(git diff --stat) != '' ]]; then
|
||||
|
@ -62,8 +70,7 @@ jobs:
|
|||
make docker-build IMG=test/helm-controller:latest \
|
||||
BUILD_PLATFORMS=linux/amd64 \
|
||||
BUILD_ARGS="--cache-from=type=local,src=/tmp/.buildx-cache \
|
||||
--cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max \
|
||||
--load"
|
||||
--cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max"
|
||||
- # Temp fix
|
||||
# https://github.com/docker/build-push-action/issues/252
|
||||
# https://github.com/moby/buildkit/issues/1896
|
||||
|
@ -91,14 +98,6 @@ jobs:
|
|||
kubectl -n helm-system rollout status deploy/helm-controller --timeout=1m
|
||||
env:
|
||||
KUBEBUILDER_ASSETS: ${{ github.workspace }}/kubebuilder/bin
|
||||
- name: Test samples
|
||||
run: |
|
||||
kubectl create ns samples
|
||||
kubectl -n samples apply -f config/samples
|
||||
kubectl -n samples wait hr/podinfo-ocirepository --for=condition=ready --timeout=4m
|
||||
kubectl -n samples wait hr/podinfo-gitrepository --for=condition=ready --timeout=4m
|
||||
kubectl -n samples wait hr/podinfo-helmrepository --for=condition=ready --timeout=4m
|
||||
kubectl delete ns samples
|
||||
- name: Install sources
|
||||
run: |
|
||||
kubectl -n helm-system apply -f config/testdata/sources
|
||||
|
@ -107,7 +106,6 @@ jobs:
|
|||
kubectl -n helm-system apply -f config/testdata/podinfo
|
||||
kubectl -n helm-system wait helmreleases/podinfo --for=condition=ready --timeout=4m
|
||||
kubectl -n helm-system wait helmreleases/podinfo-git --for=condition=ready --timeout=4m
|
||||
kubectl -n helm-system wait helmreleases/podinfo-oci --for=condition=ready --timeout=4m
|
||||
kubectl -n helm-system delete -f config/testdata/podinfo
|
||||
- name: Run dependency tests
|
||||
run: |
|
||||
|
@ -146,16 +144,6 @@ jobs:
|
|||
kubectl -n install-create-target-ns get deployment install-create-target-ns-install-create-target-ns-podinfo
|
||||
|
||||
kubectl -n helm-system delete -f config/testdata/install-create-target-ns
|
||||
- name: Run install from helmChart test
|
||||
run: |
|
||||
kubectl -n helm-system apply -f config/testdata/install-from-hc-source
|
||||
kubectl -n helm-system wait helmreleases/podinfo-from-hc --for=condition=ready --timeout=4m
|
||||
kubectl -n helm-system delete -f config/testdata/install-from-hc-source
|
||||
- name: Run install from ocirepo test
|
||||
run: |
|
||||
kubectl -n helm-system apply -f config/testdata/install-from-ocirepo-source
|
||||
kubectl -n helm-system wait helmreleases/podinfo-from-ocirepo --for=condition=ready --timeout=4m
|
||||
kubectl -n helm-system delete -f config/testdata/install-from-ocirepo-source
|
||||
- name: Run install fail test
|
||||
run: |
|
||||
test_name=install-fail
|
||||
|
@ -187,7 +175,7 @@ jobs:
|
|||
kubectl -n helm-system apply -f config/testdata/$test_name
|
||||
echo -n ">>> Waiting for expected conditions"
|
||||
count=0
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .TestSuccess=="False" and .Ready=="False"' )" ]; do
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="False" and .TestSuccess=="False" and .Ready=="False"' )" ]; do
|
||||
echo -n '.'
|
||||
sleep 5
|
||||
count=$((count + 1))
|
||||
|
@ -231,7 +219,7 @@ jobs:
|
|||
fi
|
||||
|
||||
kubectl -n helm-system delete -f config/testdata/$test_name
|
||||
- name: Run install fail with remediation test
|
||||
- name: Run install fail with remedition test
|
||||
run: |
|
||||
test_name=install-fail-remediate
|
||||
kubectl -n helm-system apply -f config/testdata/$test_name
|
||||
|
@ -248,22 +236,21 @@ jobs:
|
|||
done
|
||||
echo ' done'
|
||||
|
||||
# Ensure release was uninstalled.
|
||||
RELEASE_STATUS=$(helm -n helm-system history $test_name -o json | jq -r 'if length == 1 then .[0].status else empty end')
|
||||
if [ "$RELEASE_STATUS" != "uninstalled" ]; then
|
||||
echo -e "Unexpected release status: $RELEASE_STATUS"
|
||||
# Ensure release does not exist (was uninstalled).
|
||||
HISTORY=$(helm -n helm-system history $test_name 2>&1; exit 0)
|
||||
if [ "$HISTORY" != 'Error: release: not found' ]; then
|
||||
echo -e "Unexpected release history: $HISTORY"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl -n helm-system delete -f config/testdata/$test_name
|
||||
helm -n helm-system delete $test_name
|
||||
- name: Run install fail with retry test
|
||||
run: |
|
||||
test_name=install-fail-retry
|
||||
kubectl -n helm-system apply -f config/testdata/$test_name
|
||||
echo -n ">>> Waiting for expected conditions"
|
||||
count=0
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.installFailures == 2 and ( .status.conditions | map( { (.type): .status } ) | add | .Released=="False" and .Ready=="False" and .Stalled=="True" )' )" ]; do
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.installFailures == 2 and ( .status.conditions | map( { (.type): .status } ) | add | .Released=="False" and .Ready=="False" )' )" ]; do
|
||||
echo -n '.'
|
||||
sleep 5
|
||||
count=$((count + 1))
|
||||
|
@ -309,7 +296,7 @@ jobs:
|
|||
kubectl -n helm-system apply -f config/testdata/$test_name/upgrade.yaml
|
||||
echo -n ">>> Waiting for expected conditions"
|
||||
count=0
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="False" and .Ready=="False" and .Stalled=="True"' )" ]; do
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="False" and .Ready=="False"' )" ]; do
|
||||
echo -n '.'
|
||||
sleep 5
|
||||
count=$((count + 1))
|
||||
|
@ -355,7 +342,7 @@ jobs:
|
|||
kubectl -n helm-system apply -f config/testdata/$test_name/upgrade.yaml
|
||||
echo -n ">>> Waiting for expected conditions"
|
||||
count=0
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .TestSuccess=="False" and .Ready=="False" and .Stalled=="True"' )" ]; do
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="False" and .TestSuccess=="False" and .Ready=="False"' )" ]; do
|
||||
echo -n '.'
|
||||
sleep 5
|
||||
count=$((count + 1))
|
||||
|
@ -476,45 +463,6 @@ jobs:
|
|||
fi
|
||||
|
||||
kubectl delete -n helm-system -f config/testdata/$test_name/install.yaml
|
||||
- name: Run upgrade from ocirepo source
|
||||
run: |
|
||||
test_name=upgrade-from-ocirepo-source
|
||||
kubectl -n helm-system apply -f config/testdata/$test_name/install.yaml
|
||||
echo -n ">>> Waiting for expected conditions"
|
||||
count=0
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .Ready=="True"' )" ]; do
|
||||
echo -n '.'
|
||||
sleep 5
|
||||
count=$((count + 1))
|
||||
if [[ ${count} -eq 24 ]]; then
|
||||
echo ' No more retries left!'
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo ' done'
|
||||
|
||||
# Validate release was installed.
|
||||
REVISION_COUNT=$(helm -n helm-system history -o json $test_name | jq 'length')
|
||||
if [ "$REVISION_COUNT" != 1 ]; then
|
||||
echo -e "Unexpected revision count: $REVISION_COUNT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl -n helm-system apply -f config/testdata/$test_name/upgrade.yaml
|
||||
echo -n ">>> Waiting for expected conditions"
|
||||
count=0
|
||||
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="True" and .Ready=="True"' )" ]; do
|
||||
echo -n '.'
|
||||
sleep 5
|
||||
count=$((count + 1))
|
||||
if [[ ${count} -eq 24 ]]; then
|
||||
echo ' No more retries left!'
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo ' done'
|
||||
|
||||
kubectl delete -n helm-system -f config/testdata/$test_name/install.yaml
|
||||
- name: Run upgrade fail with uninstall remediation strategy test
|
||||
run: |
|
||||
test_name=upgrade-fail-remediate-uninstall
|
||||
|
@ -589,19 +537,6 @@ jobs:
|
|||
fi
|
||||
done
|
||||
echo ' done'
|
||||
- name: Run delete-ns tests
|
||||
run: |
|
||||
kubectl apply -f config/testdata/delete-ns
|
||||
kubectl -n delete-ns wait helmreleases/podinfo --for=condition=ready --timeout=2m
|
||||
kubectl delete ns delete-ns 1>/dev/null 2>&1 &
|
||||
echo -n ">>> Waiting for namespace to be deleted"
|
||||
if kubectl wait --for=delete namespace delete-ns --timeout=5m; then
|
||||
echo ' Namespace deleted successfully'
|
||||
else
|
||||
echo ' Timed out waiting for namespace to be deleted'
|
||||
kubectl get all -n delete-ns
|
||||
exit 1
|
||||
fi
|
||||
- name: Run post-renderer-kustomize test
|
||||
run: |
|
||||
kubectl -n helm-system apply -f config/testdata/post-renderer-kustomize
|
||||
|
@ -617,7 +552,7 @@ jobs:
|
|||
exit 1
|
||||
fi
|
||||
kubectl -n helm-system delete -f config/testdata/post-renderer-kustomize
|
||||
- name: Bootstrap CRDs Upgrade Tests
|
||||
- name: Boostrap CRDs Upgrade Tests
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/heads/') }}
|
||||
run: |
|
||||
REF=${{ github.ref }}
|
||||
|
@ -654,6 +589,9 @@ jobs:
|
|||
- name: Debug failure
|
||||
if: failure()
|
||||
run: |
|
||||
which kubectl
|
||||
kubectl version
|
||||
helm version
|
||||
kubectl -n helm-system get helmrepositories -oyaml || true
|
||||
kubectl -n helm-system get helmcharts -oyaml || true
|
||||
kubectl -n helm-system get helmreleases -oyaml || true
|
||||
|
|
|
@ -4,9 +4,6 @@ on:
|
|||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
|
||||
env:
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
|
||||
|
@ -14,17 +11,18 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: all
|
||||
- name: Setup Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
- name: Build multi-arch container image
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: false
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
|
|
|
@ -7,29 +7,17 @@ on:
|
|||
inputs:
|
||||
tag:
|
||||
description: 'image tag prefix'
|
||||
default: 'preview'
|
||||
default: 'rc'
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CONTROLLER: ${{ github.event.repository.name }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
outputs:
|
||||
hashes: ${{ steps.slsa.outputs.hashes }}
|
||||
image_url: ${{ steps.slsa.outputs.image_url }}
|
||||
image_digest: ${{ steps.slsa.outputs.image_digest }}
|
||||
build-push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # for creating the GitHub release.
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
packages: write # for pushing and signing container images.
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup Kustomize
|
||||
uses: fluxcd/pkg/actions/kustomize@main
|
||||
- name: Prepare
|
||||
|
@ -39,122 +27,65 @@ jobs:
|
|||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF/refs\/tags\//}
|
||||
fi
|
||||
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
|
||||
echo ::set-output name=BUILD_DATE::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
echo ::set-output name=VERSION::${VERSION}
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: all
|
||||
- name: Setup Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
buildkitd-flags: "--debug"
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
||||
- name: Generate images meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
||||
- name: Publish multi-arch container image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
images: |
|
||||
fluxcd/${{ env.CONTROLLER }}
|
||||
ghcr.io/fluxcd/${{ env.CONTROLLER }}
|
||||
tags: |
|
||||
type=raw,value=${{ steps.prep.outputs.VERSION }}
|
||||
- name: Publish images
|
||||
id: build-push
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
sbom: true
|
||||
provenance: true
|
||||
push: true
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
- uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
|
||||
- name: Sign images
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 1
|
||||
tags: |
|
||||
ghcr.io/fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.VERSION }}
|
||||
docker.io/fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.VERSION }}
|
||||
labels: |
|
||||
org.opencontainers.image.title=${{ github.event.repository.name }}
|
||||
org.opencontainers.image.description=${{ github.event.repository.description }}
|
||||
org.opencontainers.image.url=${{ github.event.repository.html_url }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
org.opencontainers.image.version=${{ steps.prep.outputs.VERSION }}
|
||||
org.opencontainers.image.created=${{ steps.prep.outputs.BUILD_DATE }}
|
||||
- name: Check images
|
||||
run: |
|
||||
cosign sign --yes fluxcd/${{ env.CONTROLLER }}@${{ steps.build-push.outputs.digest }}
|
||||
cosign sign --yes ghcr.io/fluxcd/${{ env.CONTROLLER }}@${{ steps.build-push.outputs.digest }}
|
||||
- name: Generate release artifacts
|
||||
docker buildx imagetools inspect docker.io/fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.VERSION }}
|
||||
docker buildx imagetools inspect ghcr.io/fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.VERSION }}
|
||||
docker pull docker.io/fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.VERSION }}
|
||||
docker pull ghcr.io/fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.VERSION }}
|
||||
- name: Generate release manifests
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
run: |
|
||||
mkdir -p config/release
|
||||
kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml
|
||||
kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml
|
||||
- uses: anchore/sbom-action/download-syft@cee1b8e05ae5b2593a75e197229729eabaa9f8ec # v0.20.2
|
||||
- name: Create release and SBOM
|
||||
id: run-goreleaser
|
||||
- name: Create release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean --skip=validate
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Generate SLSA metadata
|
||||
id: slsa
|
||||
env:
|
||||
ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}"
|
||||
run: |
|
||||
hashes=$(echo -E $ARTIFACTS | jq --raw-output '.[] | {name, "digest": (.extra.Digest // .extra.Checksum)} | select(.digest) | {digest} + {name} | join(" ") | sub("^sha256:";"")' | base64 -w0)
|
||||
echo "hashes=$hashes" >> $GITHUB_OUTPUT
|
||||
|
||||
image_url=fluxcd/${{ env.CONTROLLER }}:${{ steps.prep.outputs.version }}
|
||||
echo "image_url=$image_url" >> $GITHUB_OUTPUT
|
||||
|
||||
image_digest=${{ steps.build-push.outputs.digest }}
|
||||
echo "image_digest=$image_digest" >> $GITHUB_OUTPUT
|
||||
|
||||
release-provenance:
|
||||
needs: [release]
|
||||
permissions:
|
||||
actions: read # for detecting the Github Actions environment.
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
contents: write # for uploading attestations to GitHub releases.
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
|
||||
with:
|
||||
provenance-name: "provenance.intoto.jsonl"
|
||||
base64-subjects: "${{ needs.release.outputs.hashes }}"
|
||||
upload-assets: true
|
||||
|
||||
dockerhub-provenance:
|
||||
needs: [release]
|
||||
permissions:
|
||||
actions: read # for detecting the Github Actions environment.
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
packages: write # for uploading attestations.
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
|
||||
with:
|
||||
image: ${{ needs.release.outputs.image_url }}
|
||||
digest: ${{ needs.release.outputs.image_digest }}
|
||||
registry-username: fluxcdbot
|
||||
secrets:
|
||||
registry-password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
|
||||
|
||||
ghcr-provenance:
|
||||
needs: [release]
|
||||
permissions:
|
||||
actions: read # for detecting the Github Actions environment.
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
packages: write # for uploading attestations.
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
|
||||
with:
|
||||
image: ghcr.io/${{ needs.release.outputs.image_url }}
|
||||
digest: ${{ needs.release.outputs.image_digest }}
|
||||
registry-username: fluxcdbot
|
||||
secrets:
|
||||
registry-password: ${{ secrets.GHCR_TOKEN }}
|
||||
prerelease: true
|
||||
artifacts: "config/release/*.yaml"
|
||||
artifactContentType: "text/plain"
|
||||
body: |
|
||||
[CHANGELOG](https://github.com/fluxcd/${{ env.CONTROLLER }}/blob/main/CHANGELOG.md)
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
@ -1,51 +1,55 @@
|
|||
name: scan
|
||||
name: Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main", "release/**" ]
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ "main", "release/**" ]
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '18 10 * * 3'
|
||||
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
security-events: write # for codeQL to write security events
|
||||
|
||||
jobs:
|
||||
fossa:
|
||||
name: FOSSA
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run FOSSA scan and upload build data
|
||||
uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1
|
||||
uses: fossa-contrib/fossa-action@v1
|
||||
with:
|
||||
# FOSSA Push-Only API Token
|
||||
fossa-api-key: 5ee8bf422db1471e0bcf2bcb289185de
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
snyk:
|
||||
name: Snyk
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/golang@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --sarif-file-output=snyk.sarif
|
||||
- name: Upload result to GitHub Code Scanning
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
with:
|
||||
sarif_file: snyk.sarif
|
||||
|
||||
codeql:
|
||||
name: CodeQL
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: 1.24.x
|
||||
cache-dependency-path: |
|
||||
**/go.sum
|
||||
**/go.mod
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: go
|
||||
# xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# xref: https://codeql.github.com/codeql-query-help/go/
|
||||
queries: security-and-quality
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
|
||||
uses: github/codeql-action/analyze@v1
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
name: sync-labels
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- .github/labels.yaml
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
labels:
|
||||
name: Run sync
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
|
||||
with:
|
||||
# Configuration file
|
||||
config-file: |
|
||||
https://raw.githubusercontent.com/fluxcd/community/main/.github/standard-labels.yaml
|
||||
.github/labels.yaml
|
||||
# Strictly declarative
|
||||
delete-other-labels: true
|
|
@ -21,5 +21,3 @@ bin
|
|||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
build/
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
project_name: helm-controller
|
||||
|
||||
builds:
|
||||
- skip: true
|
||||
|
||||
release:
|
||||
extra_files:
|
||||
- glob: config/release/*.yaml
|
||||
prerelease: "auto"
|
||||
header: |
|
||||
## Changelog
|
||||
|
||||
[{{.Tag}} changelog](https://github.com/fluxcd/{{.ProjectName}}/blob/{{.Tag}}/CHANGELOG.md)
|
||||
footer: |
|
||||
## Container images
|
||||
|
||||
- `docker.io/fluxcd/{{.ProjectName}}:{{.Tag}}`
|
||||
- `ghcr.io/fluxcd/{{.ProjectName}}:{{.Tag}}`
|
||||
|
||||
Supported architectures: `linux/amd64`, `linux/arm64` and `linux/arm/v7`.
|
||||
|
||||
The container images are built on GitHub hosted runners and are signed with cosign and GitHub OIDC.
|
||||
To verify the images and their provenance (SLSA level 3), please see the [security documentation](https://fluxcd.io/flux/security/).
|
||||
|
||||
changelog:
|
||||
disable: true
|
||||
|
||||
checksum:
|
||||
extra_files:
|
||||
- glob: config/release/*.yaml
|
||||
|
||||
source:
|
||||
enabled: true
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_source_code"
|
||||
|
||||
sboms:
|
||||
- id: source
|
||||
artifacts: source
|
||||
documents:
|
||||
- "{{ .ProjectName }}_{{ .Version }}_sbom.spdx.json"
|
||||
|
||||
# signs the checksum file
|
||||
# all files (including the sboms) are included in the checksum
|
||||
# https://goreleaser.com/customization/sign
|
||||
signs:
|
||||
- cmd: cosign
|
||||
env:
|
||||
- COSIGN_EXPERIMENTAL=1
|
||||
certificate: "${artifact}.pem"
|
||||
args:
|
||||
- sign-blob
|
||||
- "--yes"
|
||||
- "--output-certificate=${certificate}"
|
||||
- "--output-signature=${signature}"
|
||||
- "${artifact}"
|
||||
artifacts: checksum
|
||||
output: true
|
1585
CHANGELOG.md
1585
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
|
@ -1,32 +1,17 @@
|
|||
# Development
|
||||
|
||||
> **Note:** Please take a look at <https://fluxcd.io/contributing/flux/>
|
||||
> **Note:** Please take a look at <https://fluxcd.io/docs/contributing/flux/>
|
||||
> to find out about how to contribute to Flux and how to interact with the
|
||||
> Flux Development team.
|
||||
|
||||
## Installing required dependencies
|
||||
|
||||
There are a number of dependencies required to be able to run the controller and its test suite locally:
|
||||
|
||||
- [Install Go](https://golang.org/doc/install)
|
||||
- [Install Kustomize](https://kubernetes-sigs.github.io/kustomize/installation/)
|
||||
- [Install Docker](https://docs.docker.com/engine/install/)
|
||||
- (Optional) [Install Kubebuilder](https://book.kubebuilder.io/quick-start.html#installation)
|
||||
|
||||
In addition to the above, the following dependencies are also used by some of the `make` targets:
|
||||
|
||||
- `controller-gen` (v0.7.0)
|
||||
- `gen-crd-api-reference-docs` (v0.3.0)
|
||||
- `setup-envtest` (latest)
|
||||
|
||||
If any of the above dependencies are not present on your system, the first invocation of a `make` target that requires them will install them.
|
||||
|
||||
## How to run the test suite
|
||||
|
||||
Prerequisites:
|
||||
* Go >= 1.24
|
||||
* go >= 1.16
|
||||
* kubebuilder >= 2.3
|
||||
* kustomize >= 3.1
|
||||
|
||||
You can run the test suite by simply doing
|
||||
You can run the unit tests by simply doing
|
||||
|
||||
```bash
|
||||
make test
|
||||
|
@ -34,13 +19,17 @@ make test
|
|||
|
||||
## How to run the controller locally
|
||||
|
||||
Install the controller's CRDs on your test cluster:
|
||||
Install flux on your test cluster:
|
||||
|
||||
```sh
|
||||
make install
|
||||
flux install
|
||||
```
|
||||
|
||||
Note that `helm-controller` depends on [source-controller](https://github.com/fluxcd/source-controller) to acquire the Helm charts from Helm repositories. If `source-controller` is not running on your test cluster, you need to tell `helm-controller` where to find it.
|
||||
Scale the in-cluster controller to zero:
|
||||
|
||||
```sh
|
||||
kubectl -n flux-system scale deployment/helm-controller --replicas=0
|
||||
```
|
||||
|
||||
Port forward to source-controller artifacts server:
|
||||
|
||||
|
@ -54,47 +43,8 @@ Export the local address as `SOURCE_CONTROLLER_LOCALHOST`:
|
|||
export SOURCE_CONTROLLER_LOCALHOST=localhost:8080
|
||||
```
|
||||
|
||||
Alternatively, if your test cluster is already running `source-controller` and `helm-controller`, you need to scale down the in-cluster `helm-controller`:
|
||||
|
||||
```
|
||||
kubectl -n flux-system scale deployment/helm-controller --replicas=0
|
||||
```
|
||||
|
||||
Run the controller locally:
|
||||
|
||||
```sh
|
||||
make run
|
||||
```
|
||||
|
||||
## How to install the controller
|
||||
|
||||
### Building the container image
|
||||
|
||||
Set the name of the container image to be created from the source code. This will be used when building, pushing and referring to the image on YAML files:
|
||||
|
||||
```sh
|
||||
export IMG=registry-path/helm-controller:latest
|
||||
```
|
||||
|
||||
Build the container image, tagging it as `$(IMG)`:
|
||||
|
||||
```sh
|
||||
make docker-build
|
||||
```
|
||||
|
||||
Push the image into the repository:
|
||||
|
||||
```sh
|
||||
make docker-push
|
||||
```
|
||||
|
||||
**Note**: `make docker-build` will build an image for the `amd64` architecture.
|
||||
|
||||
|
||||
### Deploying into a cluster
|
||||
|
||||
Deploy `helm-controller` into the cluster that is configured in the local kubeconfig file (i.e. `~/.kube/config`):
|
||||
|
||||
```sh
|
||||
make deploy
|
||||
```
|
22
Dockerfile
22
Dockerfile
|
@ -1,10 +1,9 @@
|
|||
ARG GO_VERSION=1.24
|
||||
ARG XX_VERSION=1.6.1
|
||||
ARG XX_VERSION=1.0.0-rc.2
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
|
||||
# Docker buildkit multi-arch build requires golang alpine
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.16-alpine as builder
|
||||
|
||||
# Copy the build utilities.
|
||||
COPY --from=xx / /
|
||||
|
@ -25,19 +24,24 @@ RUN go mod download
|
|||
|
||||
# copy source code
|
||||
COPY main.go main.go
|
||||
COPY controllers/ controllers/
|
||||
COPY internal/ internal/
|
||||
|
||||
# build without specifing the arch
|
||||
ENV CGO_ENABLED=0
|
||||
RUN xx-go build -trimpath -a -o helm-controller main.go
|
||||
RUN xx-go build -a -o helm-controller main.go
|
||||
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.13
|
||||
|
||||
RUN apk add --no-cache ca-certificates \
|
||||
&& update-ca-certificates
|
||||
# link repo to the GitHub Container Registry image
|
||||
LABEL org.opencontainers.image.source="https://github.com/fluxcd/helm-controller"
|
||||
|
||||
RUN apk add --no-cache ca-certificates tini
|
||||
|
||||
COPY --from=builder /workspace/helm-controller /usr/local/bin/
|
||||
|
||||
USER 65534:65534
|
||||
RUN addgroup -S controller && adduser -S controller -G controller
|
||||
|
||||
ENTRYPOINT [ "helm-controller" ]
|
||||
USER controller
|
||||
|
||||
ENTRYPOINT [ "/sbin/tini", "--", "helm-controller" ]
|
||||
|
|
|
@ -8,8 +8,6 @@ from the main Flux v2 git repository, as listed in
|
|||
|
||||
https://github.com/fluxcd/flux2/blob/main/MAINTAINERS
|
||||
|
||||
Retired maintainers:
|
||||
In alphabetical order:
|
||||
|
||||
- Sean Eagan
|
||||
|
||||
Thank you for your involvement, and let us not say "farewell" ...
|
||||
Sean Eagan, AT&T <sean.eagan@att.com> (github: @seaneagan, slack: seaneagan)
|
||||
|
|
153
Makefile
153
Makefile
|
@ -3,56 +3,28 @@ IMG ?= fluxcd/helm-controller:latest
|
|||
# Produce CRDs that work back to Kubernetes 1.16
|
||||
CRD_OPTIONS ?= crd:crdVersions=v1
|
||||
|
||||
# Repository root based on Git metadata
|
||||
REPOSITORY_ROOT := $(shell git rev-parse --show-toplevel)
|
||||
BUILD_DIR := $(REPOSITORY_ROOT)/build
|
||||
|
||||
# FUZZ_TIME defines the max amount of time, in Go Duration,
|
||||
# each fuzzer should run for.
|
||||
FUZZ_TIME ?= 1m
|
||||
|
||||
# If gobin not set, create one on ./build and add to path.
|
||||
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
|
||||
ifeq (,$(shell go env GOBIN))
|
||||
GOBIN=$(BUILD_DIR)/gobin
|
||||
GOBIN=$(shell go env GOPATH)/bin
|
||||
else
|
||||
GOBIN=$(shell go env GOBIN)
|
||||
endif
|
||||
export PATH:=$(GOBIN):${PATH}
|
||||
|
||||
# Allows for defining additional Docker buildx arguments, e.g. '--push'.
|
||||
BUILD_ARGS ?= --load
|
||||
BUILD_ARGS ?=
|
||||
# Architectures to build images for.
|
||||
BUILD_PLATFORMS ?= linux/amd64
|
||||
|
||||
# Architecture to use envtest with
|
||||
ENVTEST_ARCH ?= amd64
|
||||
|
||||
# Paths to download the CRD dependency to.
|
||||
CRD_DEP_ROOT ?= $(BUILD_DIR)/config/crd/bases
|
||||
|
||||
# Keep a record of the version of the downloaded source CRDs. It is used to
|
||||
# detect and download new CRDs when the SOURCE_VER changes.
|
||||
SOURCE_VER ?= $(shell go list -m all | grep github.com/fluxcd/source-controller/api | awk '{print $$2}')
|
||||
SOURCE_CRD_VER = $(CRD_DEP_ROOT)/.src-crd-$(SOURCE_VER)
|
||||
|
||||
# HelmChart source CRD.
|
||||
HELMCHART_SOURCE_CRD ?= $(CRD_DEP_ROOT)/source.toolkit.fluxcd.io_helmcharts.yaml
|
||||
|
||||
# API (doc) generation utilities
|
||||
CONTROLLER_GEN_VERSION ?= v0.16.1
|
||||
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
|
||||
|
||||
all: manager
|
||||
|
||||
# Run tests
|
||||
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
|
||||
test: tidy generate fmt vet manifests api-docs install-envtest download-crd-deps
|
||||
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) go test ./... -coverprofile cover.out
|
||||
test: generate fmt vet manifests api-docs
|
||||
go test ./... -coverprofile cover.out
|
||||
cd api; go test ./... -coverprofile cover.out
|
||||
|
||||
# Build manager binary
|
||||
manager: generate fmt vet
|
||||
go build -o $(BUILD_DIR)/bin/manager main.go
|
||||
go build -o bin/manager main.go
|
||||
|
||||
# Run against the configured Kubernetes cluster in ~/.kube/config
|
||||
run: generate fmt vet manifests
|
||||
|
@ -92,12 +64,12 @@ manifests: controller-gen
|
|||
|
||||
# Generate API reference documentation
|
||||
api-docs: gen-crd-api-reference-docs
|
||||
$(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v2/helm.md
|
||||
$(API_REF_GEN) -api-dir=./api/v2beta1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/helmrelease.md
|
||||
|
||||
# Run go mod tidy
|
||||
tidy:
|
||||
cd api; rm -f go.sum; go mod tidy -compat=1.23
|
||||
rm -f go.sum; go mod tidy -compat=1.23
|
||||
cd api; rm -f go.sum; go mod tidy
|
||||
rm -f go.sum; go mod tidy
|
||||
|
||||
# Run go fmt against code
|
||||
fmt:
|
||||
|
@ -118,90 +90,41 @@ docker-build:
|
|||
docker buildx build \
|
||||
--platform=$(BUILD_PLATFORMS) \
|
||||
-t ${IMG} \
|
||||
--load \
|
||||
${BUILD_ARGS} .
|
||||
|
||||
# Push the docker image
|
||||
docker-push:
|
||||
docker push ${IMG}
|
||||
|
||||
# Delete previously downloaded CRDs and record the new version of the source
|
||||
# CRDs.
|
||||
$(SOURCE_CRD_VER):
|
||||
rm -f $(CRD_DEP_ROOT)/.src-crd*
|
||||
mkdir -p $(CRD_DEP_ROOT)
|
||||
$(MAKE) cleanup-crd-deps
|
||||
touch $(SOURCE_CRD_VER)
|
||||
|
||||
$(HELMCHART_SOURCE_CRD):
|
||||
curl -s https://raw.githubusercontent.com/fluxcd/source-controller/${SOURCE_VER}/config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml > $(HELMCHART_SOURCE_CRD)
|
||||
|
||||
# Download the CRDs the controller depends on
|
||||
download-crd-deps: $(SOURCE_CRD_VER) $(HELMCHART_SOURCE_CRD)
|
||||
|
||||
# Delete the downloaded CRD dependencies.
|
||||
cleanup-crd-deps:
|
||||
rm -f $(HELMCHART_SOURCE_CRD)
|
||||
|
||||
# Find or download controller-gen
|
||||
CONTROLLER_GEN = $(GOBIN)/controller-gen
|
||||
.PHONY: controller-gen
|
||||
controller-gen: ## Download controller-gen locally if necessary.
|
||||
$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION))
|
||||
controller-gen:
|
||||
ifeq (, $(shell which controller-gen))
|
||||
@{ \
|
||||
set -e ;\
|
||||
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
|
||||
cd $$CONTROLLER_GEN_TMP_DIR ;\
|
||||
go mod init tmp ;\
|
||||
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.5.0 ;\
|
||||
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
|
||||
}
|
||||
CONTROLLER_GEN=$(GOBIN)/controller-gen
|
||||
else
|
||||
CONTROLLER_GEN=$(shell which controller-gen)
|
||||
endif
|
||||
|
||||
# Find or download gen-crd-api-reference-docs
|
||||
GEN_CRD_API_REFERENCE_DOCS = $(GOBIN)/gen-crd-api-reference-docs
|
||||
.PHONY: gen-crd-api-reference-docs
|
||||
gen-crd-api-reference-docs: ## Download gen-crd-api-reference-docs locally if necessary
|
||||
$(call go-install-tool,$(GEN_CRD_API_REFERENCE_DOCS),github.com/ahmetb/gen-crd-api-reference-docs@$(GEN_API_REF_DOCS_VERSION))
|
||||
|
||||
ENVTEST_ASSETS_DIR=$(BUILD_DIR)/testbin
|
||||
ENVTEST_KUBERNETES_VERSION?=latest
|
||||
install-envtest: setup-envtest
|
||||
mkdir -p ${ENVTEST_ASSETS_DIR}
|
||||
$(ENVTEST) use $(ENVTEST_KUBERNETES_VERSION) --arch=$(ENVTEST_ARCH) --bin-dir=$(ENVTEST_ASSETS_DIR)
|
||||
|
||||
ENVTEST = $(GOBIN)/setup-envtest
|
||||
.PHONY: envtest
|
||||
setup-envtest: ## Download envtest-setup locally if necessary.
|
||||
$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest)
|
||||
|
||||
# go-install-tool will 'go install' any package $2 and install it to $1.
|
||||
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
define go-install-tool
|
||||
@[ -f $(1) ] || { \
|
||||
set -e ;\
|
||||
TMP_DIR=$$(mktemp -d) ;\
|
||||
cd $$TMP_DIR ;\
|
||||
go mod init tmp ;\
|
||||
echo "Downloading $(2)" ;\
|
||||
GOBIN=$(GOBIN) go install $(2) ;\
|
||||
rm -rf $$TMP_DIR ;\
|
||||
}
|
||||
endef
|
||||
|
||||
# Build fuzzers used by oss-fuzz.
|
||||
fuzz-build:
|
||||
rm -rf $(BUILD_DIR)/fuzz/
|
||||
mkdir -p $(BUILD_DIR)/fuzz/out/
|
||||
|
||||
docker build . --pull --tag local-fuzzing:latest -f tests/fuzz/Dockerfile.builder
|
||||
docker run --rm \
|
||||
-e FUZZING_LANGUAGE=go -e SANITIZER=address \
|
||||
-e CIFUZZ_DEBUG='True' -e OSS_FUZZ_PROJECT_NAME=fluxcd \
|
||||
-v "$(shell go env GOMODCACHE):/root/go/pkg/mod" \
|
||||
-v "$(BUILD_DIR)/fuzz/out":/out \
|
||||
local-fuzzing:latest
|
||||
|
||||
# Run each fuzzer once to ensure they will work when executed by oss-fuzz.
|
||||
fuzz-smoketest: fuzz-build
|
||||
docker run --rm \
|
||||
-v "$(BUILD_DIR)/fuzz/out":/out \
|
||||
-v "$(REPOSITORY_ROOT)/tests/fuzz/oss_fuzz_run.sh":/runner.sh \
|
||||
local-fuzzing:latest \
|
||||
bash -c "/runner.sh"
|
||||
|
||||
# Run fuzz tests for the duration set in FUZZ_TIME.
|
||||
fuzz-native:
|
||||
KUBEBUILDER_ASSETS=$(KUBEBUILDER_ASSETS) \
|
||||
FUZZ_TIME=$(FUZZ_TIME) \
|
||||
./tests/fuzz/native_go_run.sh
|
||||
gen-crd-api-reference-docs:
|
||||
ifeq (, $(shell which gen-crd-api-reference-docs))
|
||||
@{ \
|
||||
set -e ;\
|
||||
API_REF_GEN_TMP_DIR=$$(mktemp -d) ;\
|
||||
cd $$API_REF_GEN_TMP_DIR ;\
|
||||
go mod init tmp ;\
|
||||
go get github.com/ahmetb/gen-crd-api-reference-docs@v0.3.0 ;\
|
||||
rm -rf $$API_REF_GEN_TMP_DIR ;\
|
||||
}
|
||||
API_REF_GEN=$(GOBIN)/gen-crd-api-reference-docs
|
||||
else
|
||||
API_REF_GEN=$(shell which gen-crd-api-reference-docs)
|
||||
endif
|
||||
|
|
7
PROJECT
7
PROJECT
|
@ -4,11 +4,4 @@ resources:
|
|||
- group: helm
|
||||
kind: HelmRelease
|
||||
version: v2beta1
|
||||
- group: helm
|
||||
kind: HelmRelease
|
||||
version: v2beta2
|
||||
- group: helm
|
||||
kind: HelmRelease
|
||||
version: v2
|
||||
storageVersion: v2
|
||||
version: "2"
|
||||
|
|
14
README.md
14
README.md
|
@ -7,7 +7,7 @@
|
|||
[](https://github.com/fluxcd/helm-controller/releases)
|
||||
|
||||
The helm-controller is a Kubernetes operator, allowing one to declaratively
|
||||
manage Helm chart releases. It is part of a composable [GitOps toolkit](https://fluxcd.io/flux/components)
|
||||
manage Helm chart releases. It is part of a composable [GitOps toolkit](https://toolkit.fluxcd.io)
|
||||
and depends on [source-controller][] to acquire the Helm charts from Helm
|
||||
repositories.
|
||||
|
||||
|
@ -24,7 +24,7 @@ operator.
|
|||
* Supports `HelmChart` artifacts produced from `HelmRepository`,
|
||||
`GitRepository` and `Bucket` sources
|
||||
* Fetches artifacts produced by [source-controller][] from `HelmChart`
|
||||
and `OCIRepository` objects
|
||||
objects
|
||||
* Watches `HelmChart` objects for revision changes (including semver
|
||||
ranges for charts from `HelmRepository` sources)
|
||||
* Performs automated Helm actions, including Helm tests, rollbacks and
|
||||
|
@ -38,18 +38,16 @@ operator.
|
|||
[notification-controller][])
|
||||
* Built-in Kustomize compatible Helm post renderer, providing support
|
||||
for strategic merge, JSON 6902 and images patches
|
||||
* Supports detecting and correcting in-cluster changes compared to the desired
|
||||
state of the Helm release
|
||||
|
||||
## Guides
|
||||
|
||||
* [Get started with Flux](https://fluxcd.io/flux/get-started/)
|
||||
* [Manage Helm Releases](https://fluxcd.io/flux/guides/helmreleases/)
|
||||
* [Setup Notifications](https://fluxcd.io/flux/guides/notifications/)
|
||||
* [Get started with GitOps Toolkit](https://toolkit.fluxcd.io/get-started/)
|
||||
* [Manage Helm Releases](https://toolkit.fluxcd.io/guides/helmreleases/)
|
||||
* [Setup Notifications](https://toolkit.fluxcd.io/guides/notifications/)
|
||||
|
||||
## Specifications
|
||||
|
||||
* [API](docs/spec/v2/README.md)
|
||||
* [API](docs/spec/v2beta1/README.md)
|
||||
* [Controller](docs/spec/README.md)
|
||||
|
||||
[source-controller]: https://github.com/fluxcd/source-controller
|
||||
|
|
35
api/go.mod
35
api/go.mod
|
@ -1,33 +1,12 @@
|
|||
module github.com/fluxcd/helm-controller/api
|
||||
|
||||
go 1.24.0
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/fluxcd/pkg/apis/kustomize v1.11.0
|
||||
github.com/fluxcd/pkg/apis/meta v1.18.0
|
||||
k8s.io/apiextensions-apiserver v0.33.2
|
||||
k8s.io/apimachinery v0.33.2
|
||||
sigs.k8s.io/controller-runtime v0.21.0
|
||||
sigs.k8s.io/yaml v1.5.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/net v0.41.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
||||
github.com/fluxcd/pkg/apis/kustomize v0.1.0
|
||||
github.com/fluxcd/pkg/apis/meta v0.10.0
|
||||
github.com/fluxcd/pkg/runtime v0.12.0
|
||||
k8s.io/apiextensions-apiserver v0.22.1
|
||||
k8s.io/apimachinery v0.22.1
|
||||
sigs.k8s.io/controller-runtime v0.9.5
|
||||
)
|
||||
|
|
856
api/go.sum
856
api/go.sum
|
@ -1,121 +1,831 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fluxcd/pkg/apis/kustomize v1.11.0 h1:0IzDgxZkc4v+5SDNCvgZhfwfkdkQLPXCner7TNaJFWE=
|
||||
github.com/fluxcd/pkg/apis/kustomize v1.11.0/go.mod h1:j302mJGDww8cn9qvMsRQ0LJ1HPAPs/IlX7CSsoJV7BI=
|
||||
github.com/fluxcd/pkg/apis/meta v1.18.0 h1:ACHrMIjlcioE9GKS7NGk62KX4NshqNewr8sBwMcXABs=
|
||||
github.com/fluxcd/pkg/apis/meta v1.18.0/go.mod h1:97l3hTwBpJbXBY+wetNbqrUsvES8B1jGioKcBUxmqd8=
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
|
||||
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fluxcd/pkg/apis/kustomize v0.1.0 h1:sauL+KHmZ0zV2ZgpsLMyDzCQudBTtaFzSys+rXn9g9w=
|
||||
github.com/fluxcd/pkg/apis/kustomize v0.1.0/go.mod h1:gEl+W5cVykCC3RfrCaqe+Pz+j4lKl2aeR4dxsom/zII=
|
||||
github.com/fluxcd/pkg/apis/meta v0.10.0 h1:N7wVGHC1cyPdT87hrDC7UwCwRwnZdQM46PBSLjG2rlE=
|
||||
github.com/fluxcd/pkg/apis/meta v0.10.0/go.mod h1:CW9X9ijMTpNe7BwnokiUOrLl/h13miwVr/3abEQLbKE=
|
||||
github.com/fluxcd/pkg/runtime v0.12.0 h1:BPZZ8bBkimpqGAPXqOf3LTaw+tcw6HgbWyCuzbbsJGs=
|
||||
github.com/fluxcd/pkg/runtime v0.12.0/go.mod h1:EyaTR2TOYcjL5U//C4yH3bt2tvTgIOSXpVRbWxUn/C4=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/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.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
|
||||
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
|
||||
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
|
||||
github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI=
|
||||
github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
|
||||
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
|
||||
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
|
||||
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
|
||||
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
|
||||
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
|
||||
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
|
||||
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=
|
||||
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
|
||||
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/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-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY=
|
||||
k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs=
|
||||
k8s.io/apiextensions-apiserver v0.33.2 h1:6gnkIbngnaUflR3XwE1mCefN3YS8yTD631JXQhsU6M8=
|
||||
k8s.io/apiextensions-apiserver v0.33.2/go.mod h1:IvVanieYsEHJImTKXGP6XCOjTwv2LUMos0YWc9O+QP8=
|
||||
k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY=
|
||||
k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
|
||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
|
||||
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
|
||||
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
|
||||
k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg=
|
||||
k8s.io/api v0.22.1 h1:ISu3tD/jRhYfSW8jI/Q1e+lRxkR7w9UwQEZ7FgslrwY=
|
||||
k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY=
|
||||
k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA=
|
||||
k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE=
|
||||
k8s.io/apiextensions-apiserver v0.22.1 h1:YSJYzlFNFSfUle+yeEXX0lSQyLEoxoPJySRupepb0gE=
|
||||
k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c=
|
||||
k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI=
|
||||
k8s.io/apimachinery v0.22.1 h1:DTARnyzmdHMz7bFWFDDm22AM4pLWTQECMpRTFu2d2OM=
|
||||
k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
|
||||
k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY=
|
||||
k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU=
|
||||
k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400=
|
||||
k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs=
|
||||
k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU=
|
||||
k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk=
|
||||
k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q=
|
||||
k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo=
|
||||
k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
|
||||
k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA=
|
||||
k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ=
|
||||
k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471 h1:DnzUXII7sVg1FJ/4JX6YDRJfLNAC7idRatPwe07suiI=
|
||||
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/controller-runtime v0.9.0/go.mod h1:TgkfvrhhEw3PlI0BRL/5xM+89y3/yc0ZDfdbTl84si8=
|
||||
sigs.k8s.io/controller-runtime v0.9.5 h1:WThcFE6cqctTn2jCZprLICO6BaKZfhsT37uAapTNfxc=
|
||||
sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2
|
||||
|
||||
import "github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
const (
|
||||
// ForceRequestAnnotation is the annotation used for triggering a one-off forced
|
||||
// Helm release, even when there are no new changes in the HelmRelease.
|
||||
// The value is interpreted as a token, and must equal the value of
|
||||
// meta.ReconcileRequestAnnotation in order to trigger a release.
|
||||
ForceRequestAnnotation string = meta.ForceRequestAnnotation
|
||||
|
||||
// ResetRequestAnnotation is the annotation used for resetting the failure counts
|
||||
// of a HelmRelease, so that it can be retried again.
|
||||
// The value is interpreted as a token, and must equal the value of
|
||||
// meta.ReconcileRequestAnnotation in order to reset the failure counts.
|
||||
ResetRequestAnnotation string = "reconcile.fluxcd.io/resetAt"
|
||||
)
|
||||
|
||||
// ShouldHandleResetRequest returns true if the HelmRelease has a reset request
|
||||
// annotation, and the value of the annotation matches the value of the
|
||||
// meta.ReconcileRequestAnnotation annotation.
|
||||
//
|
||||
// To ensure that the reset request is handled only once, the value of
|
||||
// HelmReleaseStatus.LastHandledResetAt is updated to match the value of the
|
||||
// reset request annotation (even if the reset request is not handled because
|
||||
// the value of the meta.ReconcileRequestAnnotation annotation does not match).
|
||||
func ShouldHandleResetRequest(obj *HelmRelease) bool {
|
||||
return meta.HandleAnnotationRequest(obj, ResetRequestAnnotation, &obj.Status.LastHandledResetAt)
|
||||
}
|
||||
|
||||
// ShouldHandleForceRequest returns true if the HelmRelease has a force request
|
||||
// annotation, and the value of the annotation matches the value of the
|
||||
// meta.ReconcileRequestAnnotation annotation.
|
||||
//
|
||||
// To ensure that the force request is handled only once, the value of
|
||||
// HelmReleaseStatus.LastHandledForceAt is updated to match the value of the
|
||||
// force request annotation (even if the force request is not handled because
|
||||
// the value of the meta.ReconcileRequestAnnotation annotation does not match).
|
||||
func ShouldHandleForceRequest(obj *HelmRelease) bool {
|
||||
return meta.ShouldHandleForceRequest(obj)
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
)
|
||||
|
||||
func TestShouldHandleResetRequest(t *testing.T) {
|
||||
obj := &HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
meta.ReconcileRequestAnnotation: "b",
|
||||
ResetRequestAnnotation: "b",
|
||||
},
|
||||
},
|
||||
Status: HelmReleaseStatus{
|
||||
LastHandledResetAt: "a",
|
||||
ReconcileRequestStatus: meta.ReconcileRequestStatus{
|
||||
LastHandledReconcileAt: "a",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if !ShouldHandleResetRequest(obj) {
|
||||
t.Error("ShouldHandleResetRequest() = false")
|
||||
}
|
||||
|
||||
if obj.Status.LastHandledResetAt != "b" {
|
||||
t.Error("ShouldHandleResetRequest did not update LastHandledResetAt")
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2
|
||||
|
||||
const (
|
||||
// ReleasedCondition represents the status of the last release attempt
|
||||
// (install/upgrade/test) against the latest desired state.
|
||||
ReleasedCondition string = "Released"
|
||||
|
||||
// TestSuccessCondition represents the status of the last test attempt against
|
||||
// the latest desired state.
|
||||
TestSuccessCondition string = "TestSuccess"
|
||||
|
||||
// RemediatedCondition represents the status of the last remediation attempt
|
||||
// (uninstall/rollback) due to a failure of the last release attempt against the
|
||||
// latest desired state.
|
||||
RemediatedCondition string = "Remediated"
|
||||
)
|
||||
|
||||
const (
|
||||
// InstallSucceededReason represents the fact that the Helm install for the
|
||||
// HelmRelease succeeded.
|
||||
InstallSucceededReason string = "InstallSucceeded"
|
||||
|
||||
// InstallFailedReason represents the fact that the Helm install for the
|
||||
// HelmRelease failed.
|
||||
InstallFailedReason string = "InstallFailed"
|
||||
|
||||
// UpgradeSucceededReason represents the fact that the Helm upgrade for the
|
||||
// HelmRelease succeeded.
|
||||
UpgradeSucceededReason string = "UpgradeSucceeded"
|
||||
|
||||
// UpgradeFailedReason represents the fact that the Helm upgrade for the
|
||||
// HelmRelease failed.
|
||||
UpgradeFailedReason string = "UpgradeFailed"
|
||||
|
||||
// TestSucceededReason represents the fact that the Helm tests for the
|
||||
// HelmRelease succeeded.
|
||||
TestSucceededReason string = "TestSucceeded"
|
||||
|
||||
// TestFailedReason represents the fact that the Helm tests for the HelmRelease
|
||||
// failed.
|
||||
TestFailedReason string = "TestFailed"
|
||||
|
||||
// RollbackSucceededReason represents the fact that the Helm rollback for the
|
||||
// HelmRelease succeeded.
|
||||
RollbackSucceededReason string = "RollbackSucceeded"
|
||||
|
||||
// RollbackFailedReason represents the fact that the Helm test for the
|
||||
// HelmRelease failed.
|
||||
RollbackFailedReason string = "RollbackFailed"
|
||||
|
||||
// UninstallSucceededReason represents the fact that the Helm uninstall for the
|
||||
// HelmRelease succeeded.
|
||||
UninstallSucceededReason string = "UninstallSucceeded"
|
||||
|
||||
// UninstallFailedReason represents the fact that the Helm uninstall for the
|
||||
// HelmRelease failed.
|
||||
UninstallFailedReason string = "UninstallFailed"
|
||||
|
||||
// ArtifactFailedReason represents the fact that the artifact download for the
|
||||
// HelmRelease failed.
|
||||
ArtifactFailedReason string = "ArtifactFailed"
|
||||
|
||||
// DependencyNotReadyReason represents the fact that
|
||||
// one of the dependencies is not ready.
|
||||
DependencyNotReadyReason string = "DependencyNotReady"
|
||||
)
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2 contains API Schema definitions for the helm v2 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=helm.toolkit.fluxcd.io
|
||||
package v2
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "helm.toolkit.fluxcd.io", Version: "v2"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2
|
||||
|
||||
// CrossNamespaceObjectReference contains enough information to let you locate
|
||||
// the typed referenced object at cluster level.
|
||||
type CrossNamespaceObjectReference struct {
|
||||
// APIVersion of the referent.
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
|
||||
// Kind of the referent.
|
||||
// +kubebuilder:validation:Enum=HelmRepository;GitRepository;Bucket
|
||||
// +required
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// Name of the referent.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace of the referent.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
// +kubebuilder:validation:Optional
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// CrossNamespaceSourceReference contains enough information to let you locate
|
||||
// the typed referenced object at cluster level.
|
||||
type CrossNamespaceSourceReference struct {
|
||||
// APIVersion of the referent.
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
|
||||
// Kind of the referent.
|
||||
// +kubebuilder:validation:Enum=OCIRepository;HelmChart
|
||||
// +required
|
||||
Kind string `json:"kind"`
|
||||
|
||||
// Name of the referent.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace of the referent, defaults to the namespace of the Kubernetes
|
||||
// resource object that contains the reference.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
// +kubebuilder:validation:Optional
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// DependencyReference defines a HelmRelease dependency on another HelmRelease resource.
|
||||
type DependencyReference struct {
|
||||
// Name of the referent.
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace of the referent, defaults to the namespace of the HelmRelease
|
||||
// resource object that contains the reference.
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
|
||||
// ReadyExpr is a CEL expression that can be used to assess the readiness
|
||||
// of a dependency. When specified, the built-in readiness check
|
||||
// is replaced by the logic defined in the CEL expression.
|
||||
// To make the CEL expression additive to the built-in readiness check,
|
||||
// the feature gate `AdditiveCELDependencyCheck` must be set to `true`.
|
||||
// +optional
|
||||
ReadyExpr string `json:"readyExpr,omitempty"`
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
// snapshotStatusDeployed indicates that the release the snapshot was taken
|
||||
// from is currently deployed.
|
||||
snapshotStatusDeployed = "deployed"
|
||||
// snapshotStatusSuperseded indicates that the release the snapshot was taken
|
||||
// from has been superseded by a newer release.
|
||||
snapshotStatusSuperseded = "superseded"
|
||||
|
||||
// snapshotTestPhaseFailed indicates that the test of the release the snapshot
|
||||
// was taken from has failed.
|
||||
snapshotTestPhaseFailed = "Failed"
|
||||
)
|
||||
|
||||
// Snapshots is a list of Snapshot objects.
|
||||
type Snapshots []*Snapshot
|
||||
|
||||
// Len returns the number of Snapshots.
|
||||
func (in Snapshots) Len() int {
|
||||
return len(in)
|
||||
}
|
||||
|
||||
// SortByVersion sorts the Snapshots by version, in descending order.
|
||||
func (in Snapshots) SortByVersion() {
|
||||
sort.Slice(in, func(i, j int) bool {
|
||||
return in[i].Version > in[j].Version
|
||||
})
|
||||
}
|
||||
|
||||
// Latest returns the most recent Snapshot.
|
||||
func (in Snapshots) Latest() *Snapshot {
|
||||
if len(in) == 0 {
|
||||
return nil
|
||||
}
|
||||
in.SortByVersion()
|
||||
return in[0]
|
||||
}
|
||||
|
||||
// Previous returns the most recent Snapshot before the Latest that has a
|
||||
// status of "deployed" or "superseded", or nil if there is no such Snapshot.
|
||||
// Unless ignoreTests is true, Snapshots with a test in the "Failed" phase are
|
||||
// ignored.
|
||||
func (in Snapshots) Previous(ignoreTests bool) *Snapshot {
|
||||
if len(in) < 2 {
|
||||
return nil
|
||||
}
|
||||
in.SortByVersion()
|
||||
for i := range in[1:] {
|
||||
s := in[i+1]
|
||||
if s.Status == snapshotStatusDeployed || s.Status == snapshotStatusSuperseded {
|
||||
if ignoreTests || !s.HasTestInPhase(snapshotTestPhaseFailed) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Truncate removes all Snapshots up to the Previous deployed Snapshot.
|
||||
// If there is no previous-deployed Snapshot, the most recent 5 Snapshots are
|
||||
// retained.
|
||||
func (in *Snapshots) Truncate(ignoreTests bool) {
|
||||
if in.Len() < 2 {
|
||||
return
|
||||
}
|
||||
|
||||
in.SortByVersion()
|
||||
for i := range (*in)[1:] {
|
||||
s := (*in)[i+1]
|
||||
if s.Status == snapshotStatusDeployed || s.Status == snapshotStatusSuperseded {
|
||||
if ignoreTests || !s.HasTestInPhase(snapshotTestPhaseFailed) {
|
||||
*in = (*in)[:i+2]
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if in.Len() > defaultMaxHistory {
|
||||
// If none of the Snapshots are deployed or superseded, and there
|
||||
// are more than the defaultMaxHistory, truncate to the most recent
|
||||
// Snapshots.
|
||||
*in = (*in)[:defaultMaxHistory]
|
||||
}
|
||||
}
|
||||
|
||||
// Snapshot captures a point-in-time copy of the status information for a Helm release,
|
||||
// as managed by the controller.
|
||||
type Snapshot struct {
|
||||
// APIVersion is the API version of the Snapshot.
|
||||
// Provisional: when the calculation method of the Digest field is changed,
|
||||
// this field will be used to distinguish between the old and new methods.
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
// Digest is the checksum of the release object in storage.
|
||||
// It has the format of `<algo>:<checksum>`.
|
||||
// +required
|
||||
Digest string `json:"digest"`
|
||||
// Name is the name of the release.
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
// Namespace is the namespace the release is deployed to.
|
||||
// +required
|
||||
Namespace string `json:"namespace"`
|
||||
// Version is the version of the release object in storage.
|
||||
// +required
|
||||
Version int `json:"version"`
|
||||
// Status is the current state of the release.
|
||||
// +required
|
||||
Status string `json:"status"`
|
||||
// ChartName is the chart name of the release object in storage.
|
||||
// +required
|
||||
ChartName string `json:"chartName"`
|
||||
// ChartVersion is the chart version of the release object in
|
||||
// storage.
|
||||
// +required
|
||||
ChartVersion string `json:"chartVersion"`
|
||||
// AppVersion is the chart app version of the release object in storage.
|
||||
// +optional
|
||||
AppVersion string `json:"appVersion,omitempty"`
|
||||
// ConfigDigest is the checksum of the config (better known as
|
||||
// "values") of the release object in storage.
|
||||
// It has the format of `<algo>:<checksum>`.
|
||||
// +required
|
||||
ConfigDigest string `json:"configDigest"`
|
||||
// FirstDeployed is when the release was first deployed.
|
||||
// +required
|
||||
FirstDeployed metav1.Time `json:"firstDeployed"`
|
||||
// LastDeployed is when the release was last deployed.
|
||||
// +required
|
||||
LastDeployed metav1.Time `json:"lastDeployed"`
|
||||
// Deleted is when the release was deleted.
|
||||
// +optional
|
||||
Deleted metav1.Time `json:"deleted,omitempty"`
|
||||
// TestHooks is the list of test hooks for the release as observed to be
|
||||
// run by the controller.
|
||||
// +optional
|
||||
TestHooks *map[string]*TestHookStatus `json:"testHooks,omitempty"`
|
||||
// OCIDigest is the digest of the OCI artifact associated with the release.
|
||||
// +optional
|
||||
OCIDigest string `json:"ociDigest,omitempty"`
|
||||
}
|
||||
|
||||
// FullReleaseName returns the full name of the release in the format
|
||||
// of '<namespace>/<name>.<version>
|
||||
func (in *Snapshot) FullReleaseName() string {
|
||||
if in == nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s/%s.v%d", in.Namespace, in.Name, in.Version)
|
||||
}
|
||||
|
||||
// VersionedChartName returns the full name of the chart in the format of
|
||||
// '<name>@<version>'.
|
||||
func (in *Snapshot) VersionedChartName() string {
|
||||
if in == nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s@%s", in.ChartName, in.ChartVersion)
|
||||
}
|
||||
|
||||
// HasBeenTested returns true if TestHooks is not nil. This includes an empty
|
||||
// map, which indicates the chart has no tests.
|
||||
func (in *Snapshot) HasBeenTested() bool {
|
||||
return in != nil && in.TestHooks != nil
|
||||
}
|
||||
|
||||
// GetTestHooks returns the TestHooks for the release if not nil.
|
||||
func (in *Snapshot) GetTestHooks() map[string]*TestHookStatus {
|
||||
if in == nil || in.TestHooks == nil {
|
||||
return nil
|
||||
}
|
||||
return *in.TestHooks
|
||||
}
|
||||
|
||||
// HasTestInPhase returns true if any of the TestHooks is in the given phase.
|
||||
func (in *Snapshot) HasTestInPhase(phase string) bool {
|
||||
if in != nil {
|
||||
for _, h := range in.GetTestHooks() {
|
||||
if h.Phase == phase {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SetTestHooks sets the TestHooks for the release.
|
||||
func (in *Snapshot) SetTestHooks(hooks map[string]*TestHookStatus) {
|
||||
if in == nil || hooks == nil {
|
||||
return
|
||||
}
|
||||
in.TestHooks = &hooks
|
||||
}
|
||||
|
||||
// Targets returns true if the Snapshot targets the given release data.
|
||||
func (in *Snapshot) Targets(name, namespace string, version int) bool {
|
||||
if in != nil {
|
||||
return in.Name == name && in.Namespace == namespace && in.Version == version
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TestHookStatus holds the status information for a test hook as observed
|
||||
// to be run by the controller.
|
||||
type TestHookStatus struct {
|
||||
// LastStarted is the time the test hook was last started.
|
||||
// +optional
|
||||
LastStarted metav1.Time `json:"lastStarted,omitempty"`
|
||||
// LastCompleted is the time the test hook last completed.
|
||||
// +optional
|
||||
LastCompleted metav1.Time `json:"lastCompleted,omitempty"`
|
||||
// Phase the test hook was observed to be in.
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
}
|
|
@ -1,298 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 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 v2
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSnapshots_Sort(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
want Snapshots
|
||||
}{
|
||||
{
|
||||
name: "sorts by descending version",
|
||||
in: Snapshots{
|
||||
{Version: 1},
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
{Version: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "already sorted",
|
||||
in: Snapshots{
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
{Version: 1},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
{Version: 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.in.SortByVersion()
|
||||
|
||||
if !reflect.DeepEqual(tt.in, tt.want) {
|
||||
t.Errorf("SortByVersion() got %v, want %v", tt.in, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshots_Latest(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
want *Snapshot
|
||||
}{
|
||||
{
|
||||
name: "returns most recent snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1},
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
},
|
||||
want: &Snapshot{Version: 3},
|
||||
},
|
||||
{
|
||||
name: "returns nil if empty",
|
||||
in: Snapshots{},
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.in.Latest(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Latest() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshots_Previous(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
ignoreTests bool
|
||||
want *Snapshot
|
||||
}{
|
||||
{
|
||||
name: "returns previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 2, Status: "deployed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 1, Status: "superseded"},
|
||||
},
|
||||
want: &Snapshot{Version: 2, Status: "deployed"},
|
||||
},
|
||||
{
|
||||
name: "includes snapshots with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 1, Status: "superseded"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
ignoreTests: true,
|
||||
want: &Snapshot{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "ignores snapshots with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 1, Status: "superseded"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
ignoreTests: false,
|
||||
want: &Snapshot{Version: 2, Status: "superseded"},
|
||||
},
|
||||
{
|
||||
name: "returns nil without previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1, Status: "deployed"},
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "returns nil without snapshot matching criteria",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
ignoreTests: false,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.in.Previous(tt.ignoreTests); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Previous() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshots_Truncate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
ignoreTests bool
|
||||
want Snapshots
|
||||
}{
|
||||
{
|
||||
name: "keeps previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1, Status: "superseded"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
{Version: 4, Status: "deployed"},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ignores snapshots with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
{Version: 2, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-grpc-test-h0tc2": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-jwt-test-vzusa": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-service-test-b647e": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
}},
|
||||
},
|
||||
ignoreTests: false,
|
||||
want: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
{Version: 2, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-grpc-test-h0tc2": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-jwt-test-vzusa": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-service-test-b647e": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keeps previous snapshot with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
{Version: 2, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-grpc-test-h0tc2": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-jwt-test-vzusa": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-service-test-b647e": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
}},
|
||||
{Version: 1, Status: "superseded"},
|
||||
},
|
||||
ignoreTests: true,
|
||||
want: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "retains most recent snapshots when all have failed",
|
||||
in: Snapshots{
|
||||
{Version: 6, Status: "deployed"},
|
||||
{Version: 5, Status: "failed"},
|
||||
{Version: 4, Status: "failed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "failed"},
|
||||
{Version: 1, Status: "failed"},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 6, Status: "deployed"},
|
||||
{Version: 5, Status: "failed"},
|
||||
{Version: 4, Status: "failed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "failed"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "without previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1, Status: "deployed"},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 1, Status: "deployed"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.in.Truncate(tt.ignoreTests)
|
||||
|
||||
if !reflect.DeepEqual(tt.in, tt.want) {
|
||||
t.Errorf("Truncate() got %v, want %v", tt.in, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,774 +0,0 @@
|
|||
//go:build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2024 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.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
"github.com/fluxcd/pkg/apis/kustomize"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CommonMetadata) DeepCopyInto(out *CommonMetadata) {
|
||||
*out = *in
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonMetadata.
|
||||
func (in *CommonMetadata) DeepCopy() *CommonMetadata {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CommonMetadata)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CrossNamespaceObjectReference) DeepCopyInto(out *CrossNamespaceObjectReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossNamespaceObjectReference.
|
||||
func (in *CrossNamespaceObjectReference) DeepCopy() *CrossNamespaceObjectReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CrossNamespaceObjectReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CrossNamespaceSourceReference) DeepCopyInto(out *CrossNamespaceSourceReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossNamespaceSourceReference.
|
||||
func (in *CrossNamespaceSourceReference) DeepCopy() *CrossNamespaceSourceReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CrossNamespaceSourceReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DependencyReference) DeepCopyInto(out *DependencyReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DependencyReference.
|
||||
func (in *DependencyReference) DeepCopy() *DependencyReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DependencyReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DriftDetection) DeepCopyInto(out *DriftDetection) {
|
||||
*out = *in
|
||||
if in.Ignore != nil {
|
||||
in, out := &in.Ignore, &out.Ignore
|
||||
*out = make([]IgnoreRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriftDetection.
|
||||
func (in *DriftDetection) DeepCopy() *DriftDetection {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DriftDetection)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Filter) DeepCopyInto(out *Filter) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Filter.
|
||||
func (in *Filter) DeepCopy() *Filter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Filter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplate) DeepCopyInto(out *HelmChartTemplate) {
|
||||
*out = *in
|
||||
if in.ObjectMeta != nil {
|
||||
in, out := &in.ObjectMeta, &out.ObjectMeta
|
||||
*out = new(HelmChartTemplateObjectMeta)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplate.
|
||||
func (in *HelmChartTemplate) DeepCopy() *HelmChartTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateObjectMeta) DeepCopyInto(out *HelmChartTemplateObjectMeta) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateObjectMeta.
|
||||
func (in *HelmChartTemplateObjectMeta) DeepCopy() *HelmChartTemplateObjectMeta {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateObjectMeta)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateSpec) DeepCopyInto(out *HelmChartTemplateSpec) {
|
||||
*out = *in
|
||||
out.SourceRef = in.SourceRef
|
||||
if in.Interval != nil {
|
||||
in, out := &in.Interval, &out.Interval
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.ValuesFiles != nil {
|
||||
in, out := &in.ValuesFiles, &out.ValuesFiles
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Verify != nil {
|
||||
in, out := &in.Verify, &out.Verify
|
||||
*out = new(HelmChartTemplateVerification)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateSpec.
|
||||
func (in *HelmChartTemplateSpec) DeepCopy() *HelmChartTemplateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateVerification) DeepCopyInto(out *HelmChartTemplateVerification) {
|
||||
*out = *in
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(meta.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateVerification.
|
||||
func (in *HelmChartTemplateVerification) DeepCopy() *HelmChartTemplateVerification {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateVerification)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmRelease) DeepCopyInto(out *HelmRelease) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmRelease.
|
||||
func (in *HelmRelease) DeepCopy() *HelmRelease {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmRelease)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *HelmRelease) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmReleaseList) DeepCopyInto(out *HelmReleaseList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]HelmRelease, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmReleaseList.
|
||||
func (in *HelmReleaseList) DeepCopy() *HelmReleaseList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmReleaseList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *HelmReleaseList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmReleaseSpec) DeepCopyInto(out *HelmReleaseSpec) {
|
||||
*out = *in
|
||||
if in.Chart != nil {
|
||||
in, out := &in.Chart, &out.Chart
|
||||
*out = new(HelmChartTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ChartRef != nil {
|
||||
in, out := &in.ChartRef, &out.ChartRef
|
||||
*out = new(CrossNamespaceSourceReference)
|
||||
**out = **in
|
||||
}
|
||||
out.Interval = in.Interval
|
||||
if in.KubeConfig != nil {
|
||||
in, out := &in.KubeConfig, &out.KubeConfig
|
||||
*out = new(meta.KubeConfigReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.DependsOn != nil {
|
||||
in, out := &in.DependsOn, &out.DependsOn
|
||||
*out = make([]DependencyReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.MaxHistory != nil {
|
||||
in, out := &in.MaxHistory, &out.MaxHistory
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.PersistentClient != nil {
|
||||
in, out := &in.PersistentClient, &out.PersistentClient
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.DriftDetection != nil {
|
||||
in, out := &in.DriftDetection, &out.DriftDetection
|
||||
*out = new(DriftDetection)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Install != nil {
|
||||
in, out := &in.Install, &out.Install
|
||||
*out = new(Install)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Upgrade != nil {
|
||||
in, out := &in.Upgrade, &out.Upgrade
|
||||
*out = new(Upgrade)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Test != nil {
|
||||
in, out := &in.Test, &out.Test
|
||||
*out = new(Test)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Rollback != nil {
|
||||
in, out := &in.Rollback, &out.Rollback
|
||||
*out = new(Rollback)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Uninstall != nil {
|
||||
in, out := &in.Uninstall, &out.Uninstall
|
||||
*out = new(Uninstall)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ValuesFrom != nil {
|
||||
in, out := &in.ValuesFrom, &out.ValuesFrom
|
||||
*out = make([]meta.ValuesReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = new(apiextensionsv1.JSON)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.CommonMetadata != nil {
|
||||
in, out := &in.CommonMetadata, &out.CommonMetadata
|
||||
*out = new(CommonMetadata)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.PostRenderers != nil {
|
||||
in, out := &in.PostRenderers, &out.PostRenderers
|
||||
*out = make([]PostRenderer, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmReleaseSpec.
|
||||
func (in *HelmReleaseSpec) DeepCopy() *HelmReleaseSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmReleaseSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmReleaseStatus) DeepCopyInto(out *HelmReleaseStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.History != nil {
|
||||
in, out := &in.History, &out.History
|
||||
*out = make(Snapshots, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(Snapshot)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.LastAttemptedReleaseActionDuration != nil {
|
||||
in, out := &in.LastAttemptedReleaseActionDuration, &out.LastAttemptedReleaseActionDuration
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
out.ReconcileRequestStatus = in.ReconcileRequestStatus
|
||||
out.ForceRequestStatus = in.ForceRequestStatus
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmReleaseStatus.
|
||||
func (in *HelmReleaseStatus) DeepCopy() *HelmReleaseStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmReleaseStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *IgnoreRule) DeepCopyInto(out *IgnoreRule) {
|
||||
*out = *in
|
||||
if in.Paths != nil {
|
||||
in, out := &in.Paths, &out.Paths
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Target != nil {
|
||||
in, out := &in.Target, &out.Target
|
||||
*out = new(kustomize.Selector)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IgnoreRule.
|
||||
func (in *IgnoreRule) DeepCopy() *IgnoreRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(IgnoreRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Install) DeepCopyInto(out *Install) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Remediation != nil {
|
||||
in, out := &in.Remediation, &out.Remediation
|
||||
*out = new(InstallRemediation)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Install.
|
||||
func (in *Install) DeepCopy() *Install {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Install)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InstallRemediation) DeepCopyInto(out *InstallRemediation) {
|
||||
*out = *in
|
||||
if in.IgnoreTestFailures != nil {
|
||||
in, out := &in.IgnoreTestFailures, &out.IgnoreTestFailures
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.RemediateLastFailure != nil {
|
||||
in, out := &in.RemediateLastFailure, &out.RemediateLastFailure
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallRemediation.
|
||||
func (in *InstallRemediation) DeepCopy() *InstallRemediation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InstallRemediation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Kustomize) DeepCopyInto(out *Kustomize) {
|
||||
*out = *in
|
||||
if in.Patches != nil {
|
||||
in, out := &in.Patches, &out.Patches
|
||||
*out = make([]kustomize.Patch, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Images != nil {
|
||||
in, out := &in.Images, &out.Images
|
||||
*out = make([]kustomize.Image, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kustomize.
|
||||
func (in *Kustomize) DeepCopy() *Kustomize {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Kustomize)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PostRenderer) DeepCopyInto(out *PostRenderer) {
|
||||
*out = *in
|
||||
if in.Kustomize != nil {
|
||||
in, out := &in.Kustomize, &out.Kustomize
|
||||
*out = new(Kustomize)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostRenderer.
|
||||
func (in *PostRenderer) DeepCopy() *PostRenderer {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PostRenderer)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Rollback) DeepCopyInto(out *Rollback) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rollback.
|
||||
func (in *Rollback) DeepCopy() *Rollback {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Rollback)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Snapshot) DeepCopyInto(out *Snapshot) {
|
||||
*out = *in
|
||||
in.FirstDeployed.DeepCopyInto(&out.FirstDeployed)
|
||||
in.LastDeployed.DeepCopyInto(&out.LastDeployed)
|
||||
in.Deleted.DeepCopyInto(&out.Deleted)
|
||||
if in.TestHooks != nil {
|
||||
in, out := &in.TestHooks, &out.TestHooks
|
||||
*out = new(map[string]*TestHookStatus)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]*TestHookStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *TestHookStatus
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
inVal := (*in)[key]
|
||||
in, out := &inVal, &outVal
|
||||
*out = new(TestHookStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Snapshot.
|
||||
func (in *Snapshot) DeepCopy() *Snapshot {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Snapshot)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in Snapshots) DeepCopyInto(out *Snapshots) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(Snapshots, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(Snapshot)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Snapshots.
|
||||
func (in Snapshots) DeepCopy() Snapshots {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Snapshots)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Test) DeepCopyInto(out *Test) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Filters != nil {
|
||||
in, out := &in.Filters, &out.Filters
|
||||
*out = new([]Filter)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]Filter, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Test.
|
||||
func (in *Test) DeepCopy() *Test {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Test)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TestHookStatus) DeepCopyInto(out *TestHookStatus) {
|
||||
*out = *in
|
||||
in.LastStarted.DeepCopyInto(&out.LastStarted)
|
||||
in.LastCompleted.DeepCopyInto(&out.LastCompleted)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestHookStatus.
|
||||
func (in *TestHookStatus) DeepCopy() *TestHookStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TestHookStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Uninstall) DeepCopyInto(out *Uninstall) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.DeletionPropagation != nil {
|
||||
in, out := &in.DeletionPropagation, &out.DeletionPropagation
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Uninstall.
|
||||
func (in *Uninstall) DeepCopy() *Uninstall {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Uninstall)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Upgrade) DeepCopyInto(out *Upgrade) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Remediation != nil {
|
||||
in, out := &in.Remediation, &out.Remediation
|
||||
*out = new(UpgradeRemediation)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Upgrade.
|
||||
func (in *Upgrade) DeepCopy() *Upgrade {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Upgrade)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpgradeRemediation) DeepCopyInto(out *UpgradeRemediation) {
|
||||
*out = *in
|
||||
if in.IgnoreTestFailures != nil {
|
||||
in, out := &in.IgnoreTestFailures, &out.IgnoreTestFailures
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.RemediateLastFailure != nil {
|
||||
in, out := &in.RemediateLastFailure, &out.RemediateLastFailure
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Strategy != nil {
|
||||
in, out := &in.Strategy, &out.Strategy
|
||||
*out = new(RemediationStrategy)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpgradeRemediation.
|
||||
func (in *UpgradeRemediation) DeepCopy() *UpgradeRemediation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpgradeRemediation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
|
@ -83,16 +83,4 @@ const (
|
|||
// GetLastReleaseFailedReason represents the fact that observing the last
|
||||
// release failed.
|
||||
GetLastReleaseFailedReason string = "GetLastReleaseFailed"
|
||||
|
||||
// DependencyNotReadyReason represents the fact that
|
||||
// one of the dependencies is not ready.
|
||||
DependencyNotReadyReason string = "DependencyNotReady"
|
||||
|
||||
// ReconciliationSucceededReason represents the fact that
|
||||
// the reconciliation succeeded.
|
||||
ReconciliationSucceededReason string = "ReconciliationSucceeded"
|
||||
|
||||
// ReconciliationFailedReason represents the fact that
|
||||
// the reconciliation failed.
|
||||
ReconciliationFailedReason string = "ReconciliationFailed"
|
||||
)
|
||||
|
|
|
@ -15,9 +15,6 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
// Package v2beta1 contains API Schema definitions for the helm v2beta1 API group
|
||||
//
|
||||
// Deprecated: v2beta1 is no longer supported, use v2 instead.
|
||||
//
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=helm.toolkit.fluxcd.io
|
||||
package v2beta1
|
||||
|
|
|
@ -22,15 +22,12 @@ import (
|
|||
"time"
|
||||
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
"github.com/fluxcd/pkg/apis/kustomize"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
v2 "github.com/fluxcd/helm-controller/api/v2"
|
||||
"github.com/fluxcd/helm-controller/api/v2beta2"
|
||||
"github.com/fluxcd/pkg/runtime/dependency"
|
||||
)
|
||||
|
||||
const HelmReleaseKind = "HelmRelease"
|
||||
|
@ -38,11 +35,6 @@ const HelmReleaseFinalizer = "finalizers.fluxcd.io"
|
|||
|
||||
// Kustomize Helm PostRenderer specification.
|
||||
type Kustomize struct {
|
||||
// Strategic merge and JSON patches, defined as inline YAML objects,
|
||||
// capable of targeting objects based on kind, label and annotation selectors.
|
||||
// +optional
|
||||
Patches []kustomize.Patch `json:"patches,omitempty"`
|
||||
|
||||
// Strategic merge patches, defined as inline YAML objects.
|
||||
// +optional
|
||||
PatchesStrategicMerge []apiextensionsv1.JSON `json:"patchesStrategicMerge,omitempty"`
|
||||
|
@ -67,36 +59,19 @@ type PostRenderer struct {
|
|||
|
||||
// HelmReleaseSpec defines the desired state of a Helm release.
|
||||
type HelmReleaseSpec struct {
|
||||
// Chart defines the template of the v1beta2.HelmChart that should be created
|
||||
// Chart defines the template of the v1beta1.HelmChart that should be created
|
||||
// for this HelmRelease.
|
||||
// +required
|
||||
Chart *HelmChartTemplate `json:"chart,omitempty"`
|
||||
|
||||
// ChartRef holds a reference to a source controller resource containing the
|
||||
// Helm chart artifact.
|
||||
//
|
||||
// Note: this field is provisional to the v2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
ChartRef *v2.CrossNamespaceSourceReference `json:"chartRef,omitempty"`
|
||||
Chart HelmChartTemplate `json:"chart"`
|
||||
|
||||
// Interval at which to reconcile the Helm release.
|
||||
// This interval is approximate and may be subject to jitter to ensure
|
||||
// efficient use of resources.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +required
|
||||
Interval metav1.Duration `json:"interval"`
|
||||
|
||||
// KubeConfig for reconciling the HelmRelease on a remote cluster.
|
||||
// When used in combination with HelmReleaseSpec.ServiceAccountName,
|
||||
// forces the controller to act on behalf of that Service Account at the
|
||||
// target cluster.
|
||||
// If the --default-service-account flag is set, its value will be used as
|
||||
// a controller level fallback for when HelmReleaseSpec.ServiceAccountName
|
||||
// is empty.
|
||||
// When specified, KubeConfig takes precedence over ServiceAccountName.
|
||||
// +optional
|
||||
KubeConfig *meta.KubeConfigReference `json:"kubeConfig,omitempty"`
|
||||
KubeConfig *KubeConfig `json:"kubeConfig,omitempty"`
|
||||
|
||||
// Suspend tells the controller to suspend reconciliation for this HelmRelease,
|
||||
// it does not apply to already started reconciliations. Defaults to false.
|
||||
|
@ -127,16 +102,14 @@ type HelmReleaseSpec struct {
|
|||
// +optional
|
||||
StorageNamespace string `json:"storageNamespace,omitempty"`
|
||||
|
||||
// DependsOn may contain a meta.NamespacedObjectReference slice with
|
||||
// DependsOn may contain a dependency.CrossNamespaceDependencyReference slice with
|
||||
// references to HelmRelease resources that must be ready before this HelmRelease
|
||||
// can be reconciled.
|
||||
// +optional
|
||||
DependsOn []meta.NamespacedObjectReference `json:"dependsOn,omitempty"`
|
||||
DependsOn []dependency.CrossNamespaceDependencyReference `json:"dependsOn,omitempty"`
|
||||
|
||||
// Timeout is the time to wait for any individual Kubernetes operation (like Jobs
|
||||
// for hooks) during the performance of a Helm action. Defaults to '5m0s'.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +optional
|
||||
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
||||
|
||||
|
@ -150,30 +123,6 @@ type HelmReleaseSpec struct {
|
|||
// +optional
|
||||
ServiceAccountName string `json:"serviceAccountName,omitempty"`
|
||||
|
||||
// PersistentClient tells the controller to use a persistent Kubernetes
|
||||
// client for this release. When enabled, the client will be reused for the
|
||||
// duration of the reconciliation, instead of being created and destroyed
|
||||
// for each (step of a) Helm action.
|
||||
//
|
||||
// This can improve performance, but may cause issues with some Helm charts
|
||||
// that for example do create Custom Resource Definitions during installation
|
||||
// outside Helm's CRD lifecycle hooks, which are then not observed to be
|
||||
// available by e.g. post-install hooks.
|
||||
//
|
||||
// If not set, it defaults to true.
|
||||
//
|
||||
// +optional
|
||||
PersistentClient *bool `json:"persistentClient,omitempty"`
|
||||
|
||||
// DriftDetection holds the configuration for detecting and handling
|
||||
// differences between the manifest in the Helm storage and the resources
|
||||
// currently existing in the cluster.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
DriftDetection *v2beta2.DriftDetection `json:"driftDetection,omitempty"`
|
||||
|
||||
// Install holds the configuration for Helm install actions for this HelmRelease.
|
||||
// +optional
|
||||
Install *Install `json:"install,omitempty"`
|
||||
|
@ -252,57 +201,48 @@ func (in HelmReleaseSpec) GetUninstall() Uninstall {
|
|||
return *in.Uninstall
|
||||
}
|
||||
|
||||
// HelmChartTemplate defines the template from which the controller will
|
||||
// generate a v1beta2.HelmChart object in the same namespace as the referenced
|
||||
// v1beta2.Source.
|
||||
type HelmChartTemplate struct {
|
||||
// ObjectMeta holds the template for metadata like labels and annotations.
|
||||
// +optional
|
||||
ObjectMeta *HelmChartTemplateObjectMeta `json:"metadata,omitempty"`
|
||||
// KubeConfig references a Kubernetes secret that contains a kubeconfig file.
|
||||
type KubeConfig struct {
|
||||
// SecretRef holds the name to a secret that contains a 'value' key with
|
||||
// the kubeconfig file as the value. It must be in the same namespace as
|
||||
// the HelmRelease.
|
||||
// It is recommended that the kubeconfig is self-contained, and the secret
|
||||
// is regularly updated if credentials such as a cloud-access-token expire.
|
||||
// Cloud specific `cmd-path` auth helpers will not function without adding
|
||||
// binaries and credentials to the Pod that is responsible for reconciling
|
||||
// the HelmRelease.
|
||||
// +required
|
||||
SecretRef meta.LocalObjectReference `json:"secretRef,omitempty"`
|
||||
}
|
||||
|
||||
// Spec holds the template for the v1beta2.HelmChartSpec for this HelmRelease.
|
||||
// HelmChartTemplate defines the template from which the controller will
|
||||
// generate a v1beta1.HelmChart object in the same namespace as the referenced
|
||||
// v1beta1.Source.
|
||||
type HelmChartTemplate struct {
|
||||
// Spec holds the template for the v1beta1.HelmChartSpec for this HelmRelease.
|
||||
// +required
|
||||
Spec HelmChartTemplateSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// HelmChartTemplateObjectMeta defines the template for the ObjectMeta of a
|
||||
// v1beta2.HelmChart.
|
||||
type HelmChartTemplateObjectMeta struct {
|
||||
// Map of string keys and values that can be used to organize and categorize
|
||||
// (scope and select) objects.
|
||||
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||
// +optional
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
|
||||
// Annotations is an unstructured key value map stored with a resource that may be
|
||||
// set by external tools to store and retrieve arbitrary metadata. They are not
|
||||
// queryable and should be preserved when modifying objects.
|
||||
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// HelmChartTemplateSpec defines the template from which the controller will
|
||||
// generate a v1beta2.HelmChartSpec object.
|
||||
// generate a v1beta1.HelmChartSpec object.
|
||||
type HelmChartTemplateSpec struct {
|
||||
// The name or path the Helm chart is available at in the SourceRef.
|
||||
// +required
|
||||
Chart string `json:"chart"`
|
||||
|
||||
// Version semver expression, ignored for charts from v1beta2.GitRepository and
|
||||
// v1beta2.Bucket sources. Defaults to latest when omitted.
|
||||
// Version semver expression, ignored for charts from v1beta1.GitRepository and
|
||||
// v1beta1.Bucket sources. Defaults to latest when omitted.
|
||||
// +kubebuilder:default:=*
|
||||
// +optional
|
||||
Version string `json:"version,omitempty"`
|
||||
|
||||
// The name and namespace of the v1beta2.Source the chart is available at.
|
||||
// The name and namespace of the v1beta1.Source the chart is available at.
|
||||
// +required
|
||||
SourceRef CrossNamespaceObjectReference `json:"sourceRef"`
|
||||
|
||||
// Interval at which to check the v1beta2.Source for updates. Defaults to
|
||||
// Interval at which to check the v1beta1.Source for updates. Defaults to
|
||||
// 'HelmReleaseSpec.Interval'.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +optional
|
||||
Interval *metav1.Duration `json:"interval,omitempty"`
|
||||
|
||||
|
@ -329,17 +269,9 @@ type HelmChartTemplateSpec struct {
|
|||
// +optional
|
||||
// +deprecated
|
||||
ValuesFile string `json:"valuesFile,omitempty"`
|
||||
|
||||
// Verify contains the secret name containing the trusted public keys
|
||||
// used to verify the signature and specifies which provider to use to check
|
||||
// whether OCI image is authentic.
|
||||
// This field is only supported for OCI sources.
|
||||
// Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.
|
||||
// +optional
|
||||
Verify *HelmChartTemplateVerification `json:"verify,omitempty"`
|
||||
}
|
||||
|
||||
// GetInterval returns the configured interval for the v1beta2.HelmChart,
|
||||
// GetInterval returns the configured interval for the v1beta1.HelmChart,
|
||||
// or the given default.
|
||||
func (in HelmChartTemplate) GetInterval(defaultInterval metav1.Duration) metav1.Duration {
|
||||
if in.Spec.Interval == nil {
|
||||
|
@ -349,7 +281,7 @@ func (in HelmChartTemplate) GetInterval(defaultInterval metav1.Duration) metav1.
|
|||
}
|
||||
|
||||
// GetNamespace returns the namespace targeted namespace for the
|
||||
// v1beta2.HelmChart, or the given default.
|
||||
// v1beta1.HelmChart, or the given default.
|
||||
func (in HelmChartTemplate) GetNamespace(defaultNamespace string) string {
|
||||
if in.Spec.SourceRef.Namespace == "" {
|
||||
return defaultNamespace
|
||||
|
@ -357,19 +289,6 @@ func (in HelmChartTemplate) GetNamespace(defaultNamespace string) string {
|
|||
return in.Spec.SourceRef.Namespace
|
||||
}
|
||||
|
||||
// HelmChartTemplateVerification verifies the authenticity of an OCI Helm chart.
|
||||
type HelmChartTemplateVerification struct {
|
||||
// Provider specifies the technology used to sign the OCI Helm chart.
|
||||
// +kubebuilder:validation:Enum=cosign
|
||||
// +kubebuilder:default:=cosign
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// SecretRef specifies the Kubernetes Secret containing the
|
||||
// trusted public keys.
|
||||
// +optional
|
||||
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentAction defines a consistent interface for Install and Upgrade.
|
||||
// +kubebuilder:object:generate=false
|
||||
type DeploymentAction interface {
|
||||
|
@ -396,8 +315,6 @@ type Install struct {
|
|||
// Timeout is the time to wait for any individual Kubernetes operation (like
|
||||
// Jobs for hooks) during the performance of a Helm install action. Defaults to
|
||||
// 'HelmReleaseSpec.Timeout'.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +optional
|
||||
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
||||
|
||||
|
@ -574,8 +491,6 @@ type Upgrade struct {
|
|||
// Timeout is the time to wait for any individual Kubernetes operation (like
|
||||
// Jobs for hooks) during the performance of a Helm upgrade action. Defaults to
|
||||
// 'HelmReleaseSpec.Timeout'.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +optional
|
||||
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
||||
|
||||
|
@ -757,8 +672,6 @@ type Test struct {
|
|||
|
||||
// Timeout is the time to wait for any individual Kubernetes operation during
|
||||
// the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +optional
|
||||
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
||||
|
||||
|
@ -784,8 +697,6 @@ type Rollback struct {
|
|||
// Timeout is the time to wait for any individual Kubernetes operation (like
|
||||
// Jobs for hooks) during the performance of a Helm rollback action. Defaults to
|
||||
// 'HelmReleaseSpec.Timeout'.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +optional
|
||||
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
||||
|
||||
|
@ -832,8 +743,6 @@ type Uninstall struct {
|
|||
// Timeout is the time to wait for any individual Kubernetes operation (like
|
||||
// Jobs for hooks) during the performance of a Helm uninstall action. Defaults
|
||||
// to 'HelmReleaseSpec.Timeout'.
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
|
||||
// +optional
|
||||
Timeout *metav1.Duration `json:"timeout,omitempty"`
|
||||
|
||||
|
@ -845,18 +754,6 @@ type Uninstall struct {
|
|||
// release as deleted, but retain the release history.
|
||||
// +optional
|
||||
KeepHistory bool `json:"keepHistory,omitempty"`
|
||||
|
||||
// DisableWait disables waiting for all the resources to be deleted after
|
||||
// a Helm uninstall is performed.
|
||||
// +optional
|
||||
DisableWait bool `json:"disableWait,omitempty"`
|
||||
|
||||
// DeletionPropagation specifies the deletion propagation policy when
|
||||
// a Helm uninstall is performed.
|
||||
// +kubebuilder:default=background
|
||||
// +kubebuilder:validation:Enum=background;foreground;orphan
|
||||
// +optional
|
||||
DeletionPropagation *string `json:"deletionPropagation,omitempty"`
|
||||
}
|
||||
|
||||
// GetTimeout returns the configured timeout for the Helm uninstall action, or
|
||||
|
@ -868,26 +765,12 @@ func (in Uninstall) GetTimeout(defaultTimeout metav1.Duration) metav1.Duration {
|
|||
return *in.Timeout
|
||||
}
|
||||
|
||||
// GetDeletionPropagation returns the configured deletion propagation policy
|
||||
// for the Helm uninstall action, or 'background'.
|
||||
func (in Uninstall) GetDeletionPropagation() string {
|
||||
if in.DeletionPropagation == nil {
|
||||
return "background"
|
||||
}
|
||||
return *in.DeletionPropagation
|
||||
}
|
||||
|
||||
// HelmReleaseStatus defines the observed state of a HelmRelease.
|
||||
type HelmReleaseStatus struct {
|
||||
// ObservedGeneration is the last observed generation.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// ObservedPostRenderersDigest is the digest for the post-renderers of
|
||||
// the last successful reconciliation attempt.
|
||||
// +optional
|
||||
ObservedPostRenderersDigest string `json:"observedPostRenderersDigest,omitempty"`
|
||||
|
||||
meta.ReconcileRequestStatus `json:",inline"`
|
||||
|
||||
// Conditions holds the conditions for the HelmRelease.
|
||||
|
@ -930,62 +813,6 @@ type HelmReleaseStatus struct {
|
|||
// state. It is reset after a successful reconciliation.
|
||||
// +optional
|
||||
UpgradeFailures int64 `json:"upgradeFailures,omitempty"`
|
||||
|
||||
// StorageNamespace is the namespace of the Helm release storage for the
|
||||
// current release.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
StorageNamespace string `json:"storageNamespace,omitempty"`
|
||||
|
||||
// History holds the history of Helm releases performed for this HelmRelease
|
||||
// up to the last successfully completed release.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
History v2.Snapshots `json:"history,omitempty"`
|
||||
|
||||
// LastAttemptedGeneration is the last generation the controller attempted
|
||||
// to reconcile.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
LastAttemptedGeneration int64 `json:"lastAttemptedGeneration,omitempty"`
|
||||
|
||||
// LastAttemptedConfigDigest is the digest for the config (better known as
|
||||
// "values") of the last reconciliation attempt.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
LastAttemptedConfigDigest string `json:"lastAttemptedConfigDigest,omitempty"`
|
||||
|
||||
// LastAttemptedReleaseAction is the last release action performed for this
|
||||
// HelmRelease. It is used to determine the active remediation strategy.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
LastAttemptedReleaseAction string `json:"lastAttemptedReleaseAction,omitempty"`
|
||||
|
||||
// LastHandledForceAt holds the value of the most recent force request
|
||||
// value, so a change of the annotation value can be detected.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
LastHandledForceAt string `json:"lastHandledForceAt,omitempty"`
|
||||
|
||||
// LastHandledResetAt holds the value of the most recent reset request
|
||||
// value, so a change of the annotation value can be detected.
|
||||
//
|
||||
// Note: this field is provisional to the v2beta2 API, and not actively used
|
||||
// by v2beta1 HelmReleases.
|
||||
// +optional
|
||||
LastHandledResetAt string `json:"lastHandledResetAt,omitempty"`
|
||||
}
|
||||
|
||||
// GetHelmChart returns the namespace and name of the HelmChart.
|
||||
|
@ -993,10 +820,8 @@ func (in HelmReleaseStatus) GetHelmChart() (string, string) {
|
|||
if in.HelmChart == "" {
|
||||
return "", ""
|
||||
}
|
||||
if split := strings.Split(in.HelmChart, string(types.Separator)); len(split) > 1 {
|
||||
return split[0], split[1]
|
||||
}
|
||||
return "", ""
|
||||
split := strings.Split(in.HelmChart, string(types.Separator))
|
||||
return split[0], split[1]
|
||||
}
|
||||
|
||||
// HelmReleaseProgressing resets any failures and registers progress toward
|
||||
|
@ -1004,39 +829,23 @@ func (in HelmReleaseStatus) GetHelmChart() (string, string) {
|
|||
// 'Unknown' for meta.ProgressingReason.
|
||||
func HelmReleaseProgressing(hr HelmRelease) HelmRelease {
|
||||
hr.Status.Conditions = []metav1.Condition{}
|
||||
newCondition := metav1.Condition{
|
||||
Type: meta.ReadyCondition,
|
||||
Status: metav1.ConditionUnknown,
|
||||
Reason: meta.ProgressingReason,
|
||||
Message: "Reconciliation in progress",
|
||||
}
|
||||
apimeta.SetStatusCondition(hr.GetStatusConditions(), newCondition)
|
||||
meta.SetResourceCondition(&hr, meta.ReadyCondition, metav1.ConditionUnknown, meta.ProgressingReason,
|
||||
"Reconciliation in progress")
|
||||
resetFailureCounts(&hr)
|
||||
return hr
|
||||
}
|
||||
|
||||
// HelmReleaseNotReady registers a failed reconciliation of the given HelmRelease.
|
||||
func HelmReleaseNotReady(hr HelmRelease, reason, message string) HelmRelease {
|
||||
newCondition := metav1.Condition{
|
||||
Type: meta.ReadyCondition,
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
}
|
||||
apimeta.SetStatusCondition(hr.GetStatusConditions(), newCondition)
|
||||
meta.SetResourceCondition(&hr, meta.ReadyCondition, metav1.ConditionFalse, reason, message)
|
||||
hr.Status.Failures++
|
||||
return hr
|
||||
}
|
||||
|
||||
// HelmReleaseReady registers a successful reconciliation of the given HelmRelease.
|
||||
func HelmReleaseReady(hr HelmRelease) HelmRelease {
|
||||
newCondition := metav1.Condition{
|
||||
Type: meta.ReadyCondition,
|
||||
Status: metav1.ConditionTrue,
|
||||
Reason: ReconciliationSucceededReason,
|
||||
Message: "Release reconciliation succeeded",
|
||||
}
|
||||
apimeta.SetStatusCondition(hr.GetStatusConditions(), newCondition)
|
||||
meta.SetResourceCondition(&hr, meta.ReadyCondition, metav1.ConditionTrue, meta.ReconciliationSucceededReason,
|
||||
"Release reconciliation succeeded")
|
||||
hr.Status.LastAppliedRevision = hr.Status.LastAttemptedRevision
|
||||
resetFailureCounts(&hr)
|
||||
return hr
|
||||
|
@ -1044,8 +853,6 @@ func HelmReleaseReady(hr HelmRelease) HelmRelease {
|
|||
|
||||
// HelmReleaseAttempted registers an attempt of the given HelmRelease with the given state.
|
||||
// and returns the modified HelmRelease and a boolean indicating a state change.
|
||||
//
|
||||
// Deprecated: in favor of HelmReleaseChanged and HelmReleaseRecordAttempt.
|
||||
func HelmReleaseAttempted(hr HelmRelease, revision string, releaseRevision int, valuesChecksum string) (HelmRelease, bool) {
|
||||
changed := hr.Status.LastAttemptedRevision != revision ||
|
||||
hr.Status.LastReleaseRevision != releaseRevision ||
|
||||
|
@ -1057,31 +864,6 @@ func HelmReleaseAttempted(hr HelmRelease, revision string, releaseRevision int,
|
|||
return hr, changed
|
||||
}
|
||||
|
||||
// HelmReleaseChanged returns if the HelmRelease has changed compared to the
|
||||
// provided values.
|
||||
func HelmReleaseChanged(hr HelmRelease, revision string, releaseRevision int, valuesChecksums ...string) bool {
|
||||
return hr.Status.LastAttemptedRevision != revision ||
|
||||
hr.Status.LastReleaseRevision != releaseRevision ||
|
||||
!inStringSlice(hr.Status.LastAttemptedValuesChecksum, valuesChecksums)
|
||||
}
|
||||
|
||||
// HelmReleaseRecordAttempt returns an attempt of the given HelmRelease with the
|
||||
// given state in the Status of the provided object.
|
||||
func HelmReleaseRecordAttempt(hr *HelmRelease, revision string, releaseRevision int, valuesChecksum string) {
|
||||
hr.Status.LastAttemptedRevision = revision
|
||||
hr.Status.LastReleaseRevision = releaseRevision
|
||||
hr.Status.LastAttemptedValuesChecksum = valuesChecksum
|
||||
}
|
||||
|
||||
func inStringSlice(str string, s []string) bool {
|
||||
for _, v := range s {
|
||||
if str == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func resetFailureCounts(hr *HelmRelease) {
|
||||
hr.Status.Failures = 0
|
||||
hr.Status.InstallFailures = 0
|
||||
|
@ -1095,9 +877,13 @@ const (
|
|||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:Namespaced
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:resource:shortName=hr
|
||||
// +kubebuilder:skipversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
||||
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
|
||||
|
||||
// HelmRelease is the Schema for the helmreleases API
|
||||
type HelmRelease struct {
|
||||
|
@ -1109,12 +895,6 @@ type HelmRelease struct {
|
|||
Status HelmReleaseStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetRequeueAfter returns the duration after which the HelmRelease
|
||||
// must be reconciled again.
|
||||
func (in HelmRelease) GetRequeueAfter() time.Duration {
|
||||
return in.Spec.Interval.Duration
|
||||
}
|
||||
|
||||
// GetValues unmarshals the raw values to a map[string]interface{} and returns
|
||||
// the result.
|
||||
func (in HelmRelease) GetValues() map[string]interface{} {
|
||||
|
@ -1176,33 +956,16 @@ func (in HelmRelease) GetMaxHistory() int {
|
|||
return *in.Spec.MaxHistory
|
||||
}
|
||||
|
||||
// UsePersistentClient returns the configured PersistentClient, or the default
|
||||
// of true.
|
||||
func (in HelmRelease) UsePersistentClient() bool {
|
||||
if in.Spec.PersistentClient == nil {
|
||||
return true
|
||||
}
|
||||
return *in.Spec.PersistentClient
|
||||
// GetDependsOn returns the types.NamespacedName of the HelmRelease, and a
|
||||
// dependency.CrossNamespaceDependencyReference slice it depends on.
|
||||
func (in HelmRelease) GetDependsOn() (types.NamespacedName, []dependency.CrossNamespaceDependencyReference) {
|
||||
return types.NamespacedName{
|
||||
Namespace: in.Namespace,
|
||||
Name: in.Namespace,
|
||||
}, in.Spec.DependsOn
|
||||
}
|
||||
|
||||
// GetDependsOn returns the list of dependencies across-namespaces.
|
||||
func (in HelmRelease) GetDependsOn() []meta.NamespacedObjectReference {
|
||||
return in.Spec.DependsOn
|
||||
}
|
||||
|
||||
// GetConditions returns the status conditions of the object.
|
||||
func (in HelmRelease) GetConditions() []metav1.Condition {
|
||||
return in.Status.Conditions
|
||||
}
|
||||
|
||||
// SetConditions sets the status conditions on the object.
|
||||
func (in *HelmRelease) SetConditions(conditions []metav1.Condition) {
|
||||
in.Status.Conditions = conditions
|
||||
}
|
||||
|
||||
// GetStatusConditions returns a pointer to the Status.Conditions slice.
|
||||
//
|
||||
// Deprecated: use GetConditions instead.
|
||||
// GetStatusConditions returns a pointer to the Status.Conditions slice
|
||||
func (in *HelmRelease) GetStatusConditions() *[]metav1.Condition {
|
||||
return &in.Status.Conditions
|
||||
}
|
||||
|
|
|
@ -59,18 +59,12 @@ type ValuesReference struct {
|
|||
|
||||
// ValuesKey is the data key where the values.yaml or a specific value can be
|
||||
// found at. Defaults to 'values.yaml'.
|
||||
// When set, must be a valid Data Key, consisting of alphanumeric characters,
|
||||
// '-', '_' or '.'.
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^[\-._a-zA-Z0-9]+$`
|
||||
// +optional
|
||||
ValuesKey string `json:"valuesKey,omitempty"`
|
||||
|
||||
// TargetPath is the YAML dot notation path the value should be merged at. When
|
||||
// set, the ValuesKey is expected to be a single flat value. Defaults to 'None',
|
||||
// which results in the values getting merged at the root.
|
||||
// +kubebuilder:validation:MaxLength=250
|
||||
// +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$`
|
||||
// +optional
|
||||
TargetPath string `json:"targetPath,omitempty"`
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2024 The Flux authors
|
||||
Copyright 2021 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.
|
||||
|
@ -21,10 +21,8 @@ limitations under the License.
|
|||
package v2beta1
|
||||
|
||||
import (
|
||||
"github.com/fluxcd/helm-controller/api/v2"
|
||||
"github.com/fluxcd/helm-controller/api/v2beta2"
|
||||
"github.com/fluxcd/pkg/apis/kustomize"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
"github.com/fluxcd/pkg/runtime/dependency"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
|
@ -48,11 +46,6 @@ func (in *CrossNamespaceObjectReference) DeepCopy() *CrossNamespaceObjectReferen
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplate) DeepCopyInto(out *HelmChartTemplate) {
|
||||
*out = *in
|
||||
if in.ObjectMeta != nil {
|
||||
in, out := &in.ObjectMeta, &out.ObjectMeta
|
||||
*out = new(HelmChartTemplateObjectMeta)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
|
@ -66,35 +59,6 @@ func (in *HelmChartTemplate) DeepCopy() *HelmChartTemplate {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateObjectMeta) DeepCopyInto(out *HelmChartTemplateObjectMeta) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateObjectMeta.
|
||||
func (in *HelmChartTemplateObjectMeta) DeepCopy() *HelmChartTemplateObjectMeta {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateObjectMeta)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateSpec) DeepCopyInto(out *HelmChartTemplateSpec) {
|
||||
*out = *in
|
||||
|
@ -109,11 +73,6 @@ func (in *HelmChartTemplateSpec) DeepCopyInto(out *HelmChartTemplateSpec) {
|
|||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Verify != nil {
|
||||
in, out := &in.Verify, &out.Verify
|
||||
*out = new(HelmChartTemplateVerification)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateSpec.
|
||||
|
@ -126,26 +85,6 @@ func (in *HelmChartTemplateSpec) DeepCopy() *HelmChartTemplateSpec {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateVerification) DeepCopyInto(out *HelmChartTemplateVerification) {
|
||||
*out = *in
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(meta.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateVerification.
|
||||
func (in *HelmChartTemplateVerification) DeepCopy() *HelmChartTemplateVerification {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateVerification)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmRelease) DeepCopyInto(out *HelmRelease) {
|
||||
*out = *in
|
||||
|
@ -208,25 +147,16 @@ func (in *HelmReleaseList) DeepCopyObject() runtime.Object {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmReleaseSpec) DeepCopyInto(out *HelmReleaseSpec) {
|
||||
*out = *in
|
||||
if in.Chart != nil {
|
||||
in, out := &in.Chart, &out.Chart
|
||||
*out = new(HelmChartTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ChartRef != nil {
|
||||
in, out := &in.ChartRef, &out.ChartRef
|
||||
*out = new(v2.CrossNamespaceSourceReference)
|
||||
**out = **in
|
||||
}
|
||||
in.Chart.DeepCopyInto(&out.Chart)
|
||||
out.Interval = in.Interval
|
||||
if in.KubeConfig != nil {
|
||||
in, out := &in.KubeConfig, &out.KubeConfig
|
||||
*out = new(meta.KubeConfigReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
*out = new(KubeConfig)
|
||||
**out = **in
|
||||
}
|
||||
if in.DependsOn != nil {
|
||||
in, out := &in.DependsOn, &out.DependsOn
|
||||
*out = make([]meta.NamespacedObjectReference, len(*in))
|
||||
*out = make([]dependency.CrossNamespaceDependencyReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Timeout != nil {
|
||||
|
@ -239,16 +169,6 @@ func (in *HelmReleaseSpec) DeepCopyInto(out *HelmReleaseSpec) {
|
|||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.PersistentClient != nil {
|
||||
in, out := &in.PersistentClient, &out.PersistentClient
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.DriftDetection != nil {
|
||||
in, out := &in.DriftDetection, &out.DriftDetection
|
||||
*out = new(v2beta2.DriftDetection)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Install != nil {
|
||||
in, out := &in.Install, &out.Install
|
||||
*out = new(Install)
|
||||
|
@ -314,17 +234,6 @@ func (in *HelmReleaseStatus) DeepCopyInto(out *HelmReleaseStatus) {
|
|||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.History != nil {
|
||||
in, out := &in.History, &out.History
|
||||
*out = make(v2.Snapshots, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(v2.Snapshot)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmReleaseStatus.
|
||||
|
@ -387,16 +296,25 @@ func (in *InstallRemediation) DeepCopy() *InstallRemediation {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeConfig) DeepCopyInto(out *KubeConfig) {
|
||||
*out = *in
|
||||
out.SecretRef = in.SecretRef
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeConfig.
|
||||
func (in *KubeConfig) DeepCopy() *KubeConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Kustomize) DeepCopyInto(out *Kustomize) {
|
||||
*out = *in
|
||||
if in.Patches != nil {
|
||||
in, out := &in.Patches, &out.Patches
|
||||
*out = make([]kustomize.Patch, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.PatchesStrategicMerge != nil {
|
||||
in, out := &in.PatchesStrategicMerge, &out.PatchesStrategicMerge
|
||||
*out = make([]v1.JSON, len(*in))
|
||||
|
@ -496,11 +414,6 @@ func (in *Uninstall) DeepCopyInto(out *Uninstall) {
|
|||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.DeletionPropagation != nil {
|
||||
in, out := &in.DeletionPropagation, &out.DeletionPropagation
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Uninstall.
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
Copyright 2023 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 v2beta2
|
||||
|
||||
import "github.com/fluxcd/pkg/apis/meta"
|
||||
|
||||
const (
|
||||
// ForceRequestAnnotation is the annotation used for triggering a one-off forced
|
||||
// Helm release, even when there are no new changes in the HelmRelease.
|
||||
// The value is interpreted as a token, and must equal the value of
|
||||
// meta.ReconcileRequestAnnotation in order to trigger a release.
|
||||
ForceRequestAnnotation string = "reconcile.fluxcd.io/forceAt"
|
||||
|
||||
// ResetRequestAnnotation is the annotation used for resetting the failure counts
|
||||
// of a HelmRelease, so that it can be retried again.
|
||||
// The value is interpreted as a token, and must equal the value of
|
||||
// meta.ReconcileRequestAnnotation in order to reset the failure counts.
|
||||
ResetRequestAnnotation string = "reconcile.fluxcd.io/resetAt"
|
||||
)
|
||||
|
||||
// ShouldHandleResetRequest returns true if the HelmRelease has a reset request
|
||||
// annotation, and the value of the annotation matches the value of the
|
||||
// meta.ReconcileRequestAnnotation annotation.
|
||||
//
|
||||
// To ensure that the reset request is handled only once, the value of
|
||||
// HelmReleaseStatus.LastHandledResetAt is updated to match the value of the
|
||||
// reset request annotation (even if the reset request is not handled because
|
||||
// the value of the meta.ReconcileRequestAnnotation annotation does not match).
|
||||
func ShouldHandleResetRequest(obj *HelmRelease) bool {
|
||||
return handleRequest(obj, ResetRequestAnnotation, &obj.Status.LastHandledResetAt)
|
||||
}
|
||||
|
||||
// ShouldHandleForceRequest returns true if the HelmRelease has a force request
|
||||
// annotation, and the value of the annotation matches the value of the
|
||||
// meta.ReconcileRequestAnnotation annotation.
|
||||
//
|
||||
// To ensure that the force request is handled only once, the value of
|
||||
// HelmReleaseStatus.LastHandledForceAt is updated to match the value of the
|
||||
// force request annotation (even if the force request is not handled because
|
||||
// the value of the meta.ReconcileRequestAnnotation annotation does not match).
|
||||
func ShouldHandleForceRequest(obj *HelmRelease) bool {
|
||||
return handleRequest(obj, ForceRequestAnnotation, &obj.Status.LastHandledForceAt)
|
||||
}
|
||||
|
||||
// handleRequest returns true if the HelmRelease has a request annotation, and
|
||||
// the value of the annotation matches the value of the meta.ReconcileRequestAnnotation
|
||||
// annotation.
|
||||
//
|
||||
// The lastHandled argument is used to ensure that the request is handled only
|
||||
// once, and is updated to match the value of the request annotation (even if
|
||||
// the request is not handled because the value of the meta.ReconcileRequestAnnotation
|
||||
// annotation does not match).
|
||||
func handleRequest(obj *HelmRelease, annotation string, lastHandled *string) bool {
|
||||
requestAt, requestOk := obj.GetAnnotations()[annotation]
|
||||
reconcileAt, reconcileOk := meta.ReconcileAnnotationValue(obj.GetAnnotations())
|
||||
|
||||
var lastHandledRequest string
|
||||
if requestOk {
|
||||
lastHandledRequest = *lastHandled
|
||||
*lastHandled = requestAt
|
||||
}
|
||||
|
||||
if requestOk && reconcileOk && requestAt == reconcileAt {
|
||||
lastHandledReconcile := obj.Status.GetLastHandledReconcileRequest()
|
||||
if lastHandledReconcile != reconcileAt && lastHandledRequest != requestAt {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
Copyright 2023 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 v2beta2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
)
|
||||
|
||||
func TestShouldHandleResetRequest(t *testing.T) {
|
||||
t.Run("should handle reset request", func(t *testing.T) {
|
||||
obj := &HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
meta.ReconcileRequestAnnotation: "b",
|
||||
ResetRequestAnnotation: "b",
|
||||
},
|
||||
},
|
||||
Status: HelmReleaseStatus{
|
||||
LastHandledResetAt: "a",
|
||||
ReconcileRequestStatus: meta.ReconcileRequestStatus{
|
||||
LastHandledReconcileAt: "a",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if !ShouldHandleResetRequest(obj) {
|
||||
t.Error("ShouldHandleResetRequest() = false")
|
||||
}
|
||||
|
||||
if obj.Status.LastHandledResetAt != "b" {
|
||||
t.Error("ShouldHandleResetRequest did not update LastHandledResetAt")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestShouldHandleForceRequest(t *testing.T) {
|
||||
t.Run("should handle force request", func(t *testing.T) {
|
||||
obj := &HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
meta.ReconcileRequestAnnotation: "b",
|
||||
ForceRequestAnnotation: "b",
|
||||
},
|
||||
},
|
||||
Status: HelmReleaseStatus{
|
||||
LastHandledForceAt: "a",
|
||||
ReconcileRequestStatus: meta.ReconcileRequestStatus{
|
||||
LastHandledReconcileAt: "a",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if !ShouldHandleForceRequest(obj) {
|
||||
t.Error("ShouldHandleForceRequest() = false")
|
||||
}
|
||||
|
||||
if obj.Status.LastHandledForceAt != "b" {
|
||||
t.Error("ShouldHandleForceRequest did not update LastHandledForceAt")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Test_handleRequest(t *testing.T) {
|
||||
const requestAnnotation = "requestAnnotation"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
annotations map[string]string
|
||||
lastHandledReconcile string
|
||||
lastHandledRequest string
|
||||
want bool
|
||||
expectLastHandledRequest string
|
||||
}{
|
||||
{
|
||||
name: "valid request and reconcile annotations",
|
||||
annotations: map[string]string{
|
||||
meta.ReconcileRequestAnnotation: "b",
|
||||
requestAnnotation: "b",
|
||||
},
|
||||
want: true,
|
||||
expectLastHandledRequest: "b",
|
||||
},
|
||||
{
|
||||
name: "mismatched annotations",
|
||||
annotations: map[string]string{
|
||||
meta.ReconcileRequestAnnotation: "b",
|
||||
requestAnnotation: "c",
|
||||
},
|
||||
want: false,
|
||||
expectLastHandledRequest: "c",
|
||||
},
|
||||
{
|
||||
name: "reconcile matches previous request",
|
||||
annotations: map[string]string{
|
||||
meta.ReconcileRequestAnnotation: "b",
|
||||
requestAnnotation: "b",
|
||||
},
|
||||
lastHandledReconcile: "a",
|
||||
lastHandledRequest: "b",
|
||||
want: false,
|
||||
expectLastHandledRequest: "b",
|
||||
},
|
||||
{
|
||||
name: "request matches previous reconcile",
|
||||
annotations: map[string]string{
|
||||
meta.ReconcileRequestAnnotation: "b",
|
||||
requestAnnotation: "b",
|
||||
},
|
||||
lastHandledReconcile: "b",
|
||||
lastHandledRequest: "a",
|
||||
want: false,
|
||||
expectLastHandledRequest: "b",
|
||||
},
|
||||
{
|
||||
name: "missing annotations",
|
||||
annotations: map[string]string{},
|
||||
lastHandledRequest: "a",
|
||||
want: false,
|
||||
expectLastHandledRequest: "a",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
obj := &HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Annotations: tt.annotations,
|
||||
},
|
||||
Status: HelmReleaseStatus{
|
||||
ReconcileRequestStatus: meta.ReconcileRequestStatus{
|
||||
LastHandledReconcileAt: tt.lastHandledReconcile,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
lastHandled := tt.lastHandledRequest
|
||||
result := handleRequest(obj, requestAnnotation, &lastHandled)
|
||||
|
||||
if result != tt.want {
|
||||
t.Errorf("handleRequest() = %v, want %v", result, tt.want)
|
||||
}
|
||||
if lastHandled != tt.expectLastHandledRequest {
|
||||
t.Errorf("lastHandledRequest = %v, want %v", lastHandled, tt.expectLastHandledRequest)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v2beta2
|
||||
|
||||
const (
|
||||
// ReleasedCondition represents the status of the last release attempt
|
||||
// (install/upgrade/test) against the latest desired state.
|
||||
ReleasedCondition string = "Released"
|
||||
|
||||
// TestSuccessCondition represents the status of the last test attempt against
|
||||
// the latest desired state.
|
||||
TestSuccessCondition string = "TestSuccess"
|
||||
|
||||
// RemediatedCondition represents the status of the last remediation attempt
|
||||
// (uninstall/rollback) due to a failure of the last release attempt against the
|
||||
// latest desired state.
|
||||
RemediatedCondition string = "Remediated"
|
||||
)
|
||||
|
||||
const (
|
||||
// InstallSucceededReason represents the fact that the Helm install for the
|
||||
// HelmRelease succeeded.
|
||||
InstallSucceededReason string = "InstallSucceeded"
|
||||
|
||||
// InstallFailedReason represents the fact that the Helm install for the
|
||||
// HelmRelease failed.
|
||||
InstallFailedReason string = "InstallFailed"
|
||||
|
||||
// UpgradeSucceededReason represents the fact that the Helm upgrade for the
|
||||
// HelmRelease succeeded.
|
||||
UpgradeSucceededReason string = "UpgradeSucceeded"
|
||||
|
||||
// UpgradeFailedReason represents the fact that the Helm upgrade for the
|
||||
// HelmRelease failed.
|
||||
UpgradeFailedReason string = "UpgradeFailed"
|
||||
|
||||
// TestSucceededReason represents the fact that the Helm tests for the
|
||||
// HelmRelease succeeded.
|
||||
TestSucceededReason string = "TestSucceeded"
|
||||
|
||||
// TestFailedReason represents the fact that the Helm tests for the HelmRelease
|
||||
// failed.
|
||||
TestFailedReason string = "TestFailed"
|
||||
|
||||
// RollbackSucceededReason represents the fact that the Helm rollback for the
|
||||
// HelmRelease succeeded.
|
||||
RollbackSucceededReason string = "RollbackSucceeded"
|
||||
|
||||
// RollbackFailedReason represents the fact that the Helm test for the
|
||||
// HelmRelease failed.
|
||||
RollbackFailedReason string = "RollbackFailed"
|
||||
|
||||
// UninstallSucceededReason represents the fact that the Helm uninstall for the
|
||||
// HelmRelease succeeded.
|
||||
UninstallSucceededReason string = "UninstallSucceeded"
|
||||
|
||||
// UninstallFailedReason represents the fact that the Helm uninstall for the
|
||||
// HelmRelease failed.
|
||||
UninstallFailedReason string = "UninstallFailed"
|
||||
|
||||
// ArtifactFailedReason represents the fact that the artifact download for the
|
||||
// HelmRelease failed.
|
||||
ArtifactFailedReason string = "ArtifactFailed"
|
||||
|
||||
// InitFailedReason represents the fact that the initialization of the Helm
|
||||
// configuration failed.
|
||||
InitFailedReason string = "InitFailed"
|
||||
|
||||
// GetLastReleaseFailedReason represents the fact that observing the last
|
||||
// release failed.
|
||||
GetLastReleaseFailedReason string = "GetLastReleaseFailed"
|
||||
|
||||
// DependencyNotReadyReason represents the fact that
|
||||
// one of the dependencies is not ready.
|
||||
DependencyNotReadyReason string = "DependencyNotReady"
|
||||
|
||||
// ReconciliationSucceededReason represents the fact that
|
||||
// the reconciliation succeeded.
|
||||
ReconciliationSucceededReason string = "ReconciliationSucceeded"
|
||||
|
||||
// ReconciliationFailedReason represents the fact that
|
||||
// the reconciliation failed.
|
||||
ReconciliationFailedReason string = "ReconciliationFailed"
|
||||
)
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v2beta2 contains API Schema definitions for the helm v2beta2 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=helm.toolkit.fluxcd.io
|
||||
package v2beta2
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v2beta2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "helm.toolkit.fluxcd.io", Version: "v2beta2"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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 v2beta2
|
||||
|
||||
// CrossNamespaceObjectReference contains enough information to let you locate
|
||||
// the typed referenced object at cluster level.
|
||||
type CrossNamespaceObjectReference struct {
|
||||
// APIVersion of the referent.
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
|
||||
// Kind of the referent.
|
||||
// +kubebuilder:validation:Enum=HelmRepository;GitRepository;Bucket
|
||||
// +required
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// Name of the referent.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace of the referent.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
// +kubebuilder:validation:Optional
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// CrossNamespaceSourceReference contains enough information to let you locate
|
||||
// the typed referenced object at cluster level.
|
||||
type CrossNamespaceSourceReference struct {
|
||||
// APIVersion of the referent.
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
|
||||
// Kind of the referent.
|
||||
// +kubebuilder:validation:Enum=OCIRepository;HelmChart
|
||||
// +required
|
||||
Kind string `json:"kind"`
|
||||
|
||||
// Name of the referent.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// Namespace of the referent, defaults to the namespace of the Kubernetes
|
||||
// resource object that contains the reference.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
// +kubebuilder:validation:Optional
|
||||
// +optional
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// ValuesReference contains a reference to a resource containing Helm values,
|
||||
// and optionally the key they can be found at.
|
||||
type ValuesReference struct {
|
||||
// Kind of the values referent, valid values are ('Secret', 'ConfigMap').
|
||||
// +kubebuilder:validation:Enum=Secret;ConfigMap
|
||||
// +required
|
||||
Kind string `json:"kind"`
|
||||
|
||||
// Name of the values referent. Should reside in the same namespace as the
|
||||
// referring resource.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// ValuesKey is the data key where the values.yaml or a specific value can be
|
||||
// found at. Defaults to 'values.yaml'.
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^[\-._a-zA-Z0-9]+$`
|
||||
// +optional
|
||||
ValuesKey string `json:"valuesKey,omitempty"`
|
||||
|
||||
// TargetPath is the YAML dot notation path the value should be merged at. When
|
||||
// set, the ValuesKey is expected to be a single flat value. Defaults to 'None',
|
||||
// which results in the values getting merged at the root.
|
||||
// +kubebuilder:validation:MaxLength=250
|
||||
// +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$`
|
||||
// +optional
|
||||
TargetPath string `json:"targetPath,omitempty"`
|
||||
|
||||
// Optional marks this ValuesReference as optional. When set, a not found error
|
||||
// for the values reference is ignored, but any ValuesKey, TargetPath or
|
||||
// transient error will still result in a reconciliation failure.
|
||||
// +optional
|
||||
Optional bool `json:"optional,omitempty"`
|
||||
}
|
||||
|
||||
// GetValuesKey returns the defined ValuesKey, or the default ('values.yaml').
|
||||
func (in ValuesReference) GetValuesKey() string {
|
||||
if in.ValuesKey == "" {
|
||||
return "values.yaml"
|
||||
}
|
||||
return in.ValuesKey
|
||||
}
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
Copyright 2023 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 v2beta2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
// snapshotStatusDeployed indicates that the release the snapshot was taken
|
||||
// from is currently deployed.
|
||||
snapshotStatusDeployed = "deployed"
|
||||
// snapshotStatusSuperseded indicates that the release the snapshot was taken
|
||||
// from has been superseded by a newer release.
|
||||
snapshotStatusSuperseded = "superseded"
|
||||
|
||||
// snapshotTestPhaseFailed indicates that the test of the release the snapshot
|
||||
// was taken from has failed.
|
||||
snapshotTestPhaseFailed = "Failed"
|
||||
)
|
||||
|
||||
// Snapshots is a list of Snapshot objects.
|
||||
type Snapshots []*Snapshot
|
||||
|
||||
// Len returns the number of Snapshots.
|
||||
func (in Snapshots) Len() int {
|
||||
return len(in)
|
||||
}
|
||||
|
||||
// SortByVersion sorts the Snapshots by version, in descending order.
|
||||
func (in Snapshots) SortByVersion() {
|
||||
sort.Slice(in, func(i, j int) bool {
|
||||
return in[i].Version > in[j].Version
|
||||
})
|
||||
}
|
||||
|
||||
// Latest returns the most recent Snapshot.
|
||||
func (in Snapshots) Latest() *Snapshot {
|
||||
if len(in) == 0 {
|
||||
return nil
|
||||
}
|
||||
in.SortByVersion()
|
||||
return in[0]
|
||||
}
|
||||
|
||||
// Previous returns the most recent Snapshot before the Latest that has a
|
||||
// status of "deployed" or "superseded", or nil if there is no such Snapshot.
|
||||
// Unless ignoreTests is true, Snapshots with a test in the "Failed" phase are
|
||||
// ignored.
|
||||
func (in Snapshots) Previous(ignoreTests bool) *Snapshot {
|
||||
if len(in) < 2 {
|
||||
return nil
|
||||
}
|
||||
in.SortByVersion()
|
||||
for i := range in[1:] {
|
||||
s := in[i+1]
|
||||
if s.Status == snapshotStatusDeployed || s.Status == snapshotStatusSuperseded {
|
||||
if ignoreTests || !s.HasTestInPhase(snapshotTestPhaseFailed) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Truncate removes all Snapshots up to the Previous deployed Snapshot.
|
||||
// If there is no previous-deployed Snapshot, the most recent 5 Snapshots are
|
||||
// retained.
|
||||
func (in *Snapshots) Truncate(ignoreTests bool) {
|
||||
if in.Len() < 2 {
|
||||
return
|
||||
}
|
||||
|
||||
in.SortByVersion()
|
||||
for i := range (*in)[1:] {
|
||||
s := (*in)[i+1]
|
||||
if s.Status == snapshotStatusDeployed || s.Status == snapshotStatusSuperseded {
|
||||
if ignoreTests || !s.HasTestInPhase(snapshotTestPhaseFailed) {
|
||||
*in = (*in)[:i+2]
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if in.Len() > defaultMaxHistory {
|
||||
// If none of the Snapshots are deployed or superseded, and there
|
||||
// are more than the defaultMaxHistory, truncate to the most recent
|
||||
// Snapshots.
|
||||
*in = (*in)[:defaultMaxHistory]
|
||||
}
|
||||
}
|
||||
|
||||
// Snapshot captures a point-in-time copy of the status information for a Helm release,
|
||||
// as managed by the controller.
|
||||
type Snapshot struct {
|
||||
// APIVersion is the API version of the Snapshot.
|
||||
// Provisional: when the calculation method of the Digest field is changed,
|
||||
// this field will be used to distinguish between the old and new methods.
|
||||
// +optional
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
// Digest is the checksum of the release object in storage.
|
||||
// It has the format of `<algo>:<checksum>`.
|
||||
// +required
|
||||
Digest string `json:"digest"`
|
||||
// Name is the name of the release.
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
// Namespace is the namespace the release is deployed to.
|
||||
// +required
|
||||
Namespace string `json:"namespace"`
|
||||
// Version is the version of the release object in storage.
|
||||
// +required
|
||||
Version int `json:"version"`
|
||||
// Status is the current state of the release.
|
||||
// +required
|
||||
Status string `json:"status"`
|
||||
// ChartName is the chart name of the release object in storage.
|
||||
// +required
|
||||
ChartName string `json:"chartName"`
|
||||
// ChartVersion is the chart version of the release object in
|
||||
// storage.
|
||||
// +required
|
||||
ChartVersion string `json:"chartVersion"`
|
||||
// ConfigDigest is the checksum of the config (better known as
|
||||
// "values") of the release object in storage.
|
||||
// It has the format of `<algo>:<checksum>`.
|
||||
// +required
|
||||
ConfigDigest string `json:"configDigest"`
|
||||
// FirstDeployed is when the release was first deployed.
|
||||
// +required
|
||||
FirstDeployed metav1.Time `json:"firstDeployed"`
|
||||
// LastDeployed is when the release was last deployed.
|
||||
// +required
|
||||
LastDeployed metav1.Time `json:"lastDeployed"`
|
||||
// Deleted is when the release was deleted.
|
||||
// +optional
|
||||
Deleted metav1.Time `json:"deleted,omitempty"`
|
||||
// TestHooks is the list of test hooks for the release as observed to be
|
||||
// run by the controller.
|
||||
// +optional
|
||||
TestHooks *map[string]*TestHookStatus `json:"testHooks,omitempty"`
|
||||
// OCIDigest is the digest of the OCI artifact associated with the release.
|
||||
// +optional
|
||||
OCIDigest string `json:"ociDigest,omitempty"`
|
||||
}
|
||||
|
||||
// FullReleaseName returns the full name of the release in the format
|
||||
// of '<namespace>/<name>.<version>
|
||||
func (in *Snapshot) FullReleaseName() string {
|
||||
if in == nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s/%s.v%d", in.Namespace, in.Name, in.Version)
|
||||
}
|
||||
|
||||
// VersionedChartName returns the full name of the chart in the format of
|
||||
// '<name>@<version>'.
|
||||
func (in *Snapshot) VersionedChartName() string {
|
||||
if in == nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s@%s", in.ChartName, in.ChartVersion)
|
||||
}
|
||||
|
||||
// HasBeenTested returns true if TestHooks is not nil. This includes an empty
|
||||
// map, which indicates the chart has no tests.
|
||||
func (in *Snapshot) HasBeenTested() bool {
|
||||
return in != nil && in.TestHooks != nil
|
||||
}
|
||||
|
||||
// GetTestHooks returns the TestHooks for the release if not nil.
|
||||
func (in *Snapshot) GetTestHooks() map[string]*TestHookStatus {
|
||||
if in == nil || in.TestHooks == nil {
|
||||
return nil
|
||||
}
|
||||
return *in.TestHooks
|
||||
}
|
||||
|
||||
// HasTestInPhase returns true if any of the TestHooks is in the given phase.
|
||||
func (in *Snapshot) HasTestInPhase(phase string) bool {
|
||||
if in != nil {
|
||||
for _, h := range in.GetTestHooks() {
|
||||
if h.Phase == phase {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SetTestHooks sets the TestHooks for the release.
|
||||
func (in *Snapshot) SetTestHooks(hooks map[string]*TestHookStatus) {
|
||||
if in == nil || hooks == nil {
|
||||
return
|
||||
}
|
||||
in.TestHooks = &hooks
|
||||
}
|
||||
|
||||
// Targets returns true if the Snapshot targets the given release data.
|
||||
func (in *Snapshot) Targets(name, namespace string, version int) bool {
|
||||
if in != nil {
|
||||
return in.Name == name && in.Namespace == namespace && in.Version == version
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// TestHookStatus holds the status information for a test hook as observed
|
||||
// to be run by the controller.
|
||||
type TestHookStatus struct {
|
||||
// LastStarted is the time the test hook was last started.
|
||||
// +optional
|
||||
LastStarted metav1.Time `json:"lastStarted,omitempty"`
|
||||
// LastCompleted is the time the test hook last completed.
|
||||
// +optional
|
||||
LastCompleted metav1.Time `json:"lastCompleted,omitempty"`
|
||||
// Phase the test hook was observed to be in.
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
}
|
|
@ -1,298 +0,0 @@
|
|||
/*
|
||||
Copyright 2023 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 v2beta2
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSnapshots_Sort(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
want Snapshots
|
||||
}{
|
||||
{
|
||||
name: "sorts by descending version",
|
||||
in: Snapshots{
|
||||
{Version: 1},
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
{Version: 1},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "already sorted",
|
||||
in: Snapshots{
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
{Version: 1},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
{Version: 1},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.in.SortByVersion()
|
||||
|
||||
if !reflect.DeepEqual(tt.in, tt.want) {
|
||||
t.Errorf("SortByVersion() got %v, want %v", tt.in, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshots_Latest(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
want *Snapshot
|
||||
}{
|
||||
{
|
||||
name: "returns most recent snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1},
|
||||
{Version: 3},
|
||||
{Version: 2},
|
||||
},
|
||||
want: &Snapshot{Version: 3},
|
||||
},
|
||||
{
|
||||
name: "returns nil if empty",
|
||||
in: Snapshots{},
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.in.Latest(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Latest() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshots_Previous(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
ignoreTests bool
|
||||
want *Snapshot
|
||||
}{
|
||||
{
|
||||
name: "returns previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 2, Status: "deployed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 1, Status: "superseded"},
|
||||
},
|
||||
want: &Snapshot{Version: 2, Status: "deployed"},
|
||||
},
|
||||
{
|
||||
name: "includes snapshots with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 1, Status: "superseded"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
ignoreTests: true,
|
||||
want: &Snapshot{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "ignores snapshots with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 1, Status: "superseded"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
ignoreTests: false,
|
||||
want: &Snapshot{Version: 2, Status: "superseded"},
|
||||
},
|
||||
{
|
||||
name: "returns nil without previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1, Status: "deployed"},
|
||||
},
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "returns nil without snapshot matching criteria",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"test": {Phase: "Failed"},
|
||||
}},
|
||||
},
|
||||
ignoreTests: false,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.in.Previous(tt.ignoreTests); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("Previous() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshots_Truncate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Snapshots
|
||||
ignoreTests bool
|
||||
want Snapshots
|
||||
}{
|
||||
{
|
||||
name: "keeps previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1, Status: "superseded"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
{Version: 4, Status: "deployed"},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "superseded"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ignores snapshots with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
{Version: 2, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-grpc-test-h0tc2": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-jwt-test-vzusa": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-service-test-b647e": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
}},
|
||||
},
|
||||
ignoreTests: false,
|
||||
want: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
{Version: 2, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-grpc-test-h0tc2": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-jwt-test-vzusa": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-service-test-b647e": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keeps previous snapshot with failed tests",
|
||||
in: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
{Version: 2, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-grpc-test-h0tc2": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-jwt-test-vzusa": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
"upgrade-test-fail-podinfo-service-test-b647e": {
|
||||
Phase: "Succeeded",
|
||||
},
|
||||
}},
|
||||
{Version: 1, Status: "superseded"},
|
||||
},
|
||||
ignoreTests: true,
|
||||
want: Snapshots{
|
||||
{Version: 4, Status: "deployed"},
|
||||
{Version: 3, Status: "superseded", TestHooks: &map[string]*TestHookStatus{
|
||||
"upgrade-test-fail-podinfo-fault-test-tiz9x": {Phase: "Failed"},
|
||||
"upgrade-test-fail-podinfo-grpc-test-gddcw": {},
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "retains most recent snapshots when all have failed",
|
||||
in: Snapshots{
|
||||
{Version: 6, Status: "deployed"},
|
||||
{Version: 5, Status: "failed"},
|
||||
{Version: 4, Status: "failed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "failed"},
|
||||
{Version: 1, Status: "failed"},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 6, Status: "deployed"},
|
||||
{Version: 5, Status: "failed"},
|
||||
{Version: 4, Status: "failed"},
|
||||
{Version: 3, Status: "failed"},
|
||||
{Version: 2, Status: "failed"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "without previous snapshot",
|
||||
in: Snapshots{
|
||||
{Version: 1, Status: "deployed"},
|
||||
},
|
||||
want: Snapshots{
|
||||
{Version: 1, Status: "deployed"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.in.Truncate(tt.ignoreTests)
|
||||
|
||||
if !reflect.DeepEqual(tt.in, tt.want) {
|
||||
t.Errorf("Truncate() got %v, want %v", tt.in, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,749 +0,0 @@
|
|||
//go:build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2024 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.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v2beta2
|
||||
|
||||
import (
|
||||
"github.com/fluxcd/helm-controller/api/v2"
|
||||
"github.com/fluxcd/pkg/apis/kustomize"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CrossNamespaceObjectReference) DeepCopyInto(out *CrossNamespaceObjectReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossNamespaceObjectReference.
|
||||
func (in *CrossNamespaceObjectReference) DeepCopy() *CrossNamespaceObjectReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CrossNamespaceObjectReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CrossNamespaceSourceReference) DeepCopyInto(out *CrossNamespaceSourceReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossNamespaceSourceReference.
|
||||
func (in *CrossNamespaceSourceReference) DeepCopy() *CrossNamespaceSourceReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CrossNamespaceSourceReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DriftDetection) DeepCopyInto(out *DriftDetection) {
|
||||
*out = *in
|
||||
if in.Ignore != nil {
|
||||
in, out := &in.Ignore, &out.Ignore
|
||||
*out = make([]IgnoreRule, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriftDetection.
|
||||
func (in *DriftDetection) DeepCopy() *DriftDetection {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DriftDetection)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Filter) DeepCopyInto(out *Filter) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Filter.
|
||||
func (in *Filter) DeepCopy() *Filter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Filter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplate) DeepCopyInto(out *HelmChartTemplate) {
|
||||
*out = *in
|
||||
if in.ObjectMeta != nil {
|
||||
in, out := &in.ObjectMeta, &out.ObjectMeta
|
||||
*out = new(HelmChartTemplateObjectMeta)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplate.
|
||||
func (in *HelmChartTemplate) DeepCopy() *HelmChartTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateObjectMeta) DeepCopyInto(out *HelmChartTemplateObjectMeta) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateObjectMeta.
|
||||
func (in *HelmChartTemplateObjectMeta) DeepCopy() *HelmChartTemplateObjectMeta {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateObjectMeta)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateSpec) DeepCopyInto(out *HelmChartTemplateSpec) {
|
||||
*out = *in
|
||||
out.SourceRef = in.SourceRef
|
||||
if in.Interval != nil {
|
||||
in, out := &in.Interval, &out.Interval
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.ValuesFiles != nil {
|
||||
in, out := &in.ValuesFiles, &out.ValuesFiles
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Verify != nil {
|
||||
in, out := &in.Verify, &out.Verify
|
||||
*out = new(HelmChartTemplateVerification)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateSpec.
|
||||
func (in *HelmChartTemplateSpec) DeepCopy() *HelmChartTemplateSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmChartTemplateVerification) DeepCopyInto(out *HelmChartTemplateVerification) {
|
||||
*out = *in
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(meta.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartTemplateVerification.
|
||||
func (in *HelmChartTemplateVerification) DeepCopy() *HelmChartTemplateVerification {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmChartTemplateVerification)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmRelease) DeepCopyInto(out *HelmRelease) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmRelease.
|
||||
func (in *HelmRelease) DeepCopy() *HelmRelease {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmRelease)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *HelmRelease) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmReleaseList) DeepCopyInto(out *HelmReleaseList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]HelmRelease, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmReleaseList.
|
||||
func (in *HelmReleaseList) DeepCopy() *HelmReleaseList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmReleaseList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *HelmReleaseList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmReleaseSpec) DeepCopyInto(out *HelmReleaseSpec) {
|
||||
*out = *in
|
||||
if in.Chart != nil {
|
||||
in, out := &in.Chart, &out.Chart
|
||||
*out = new(HelmChartTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ChartRef != nil {
|
||||
in, out := &in.ChartRef, &out.ChartRef
|
||||
*out = new(CrossNamespaceSourceReference)
|
||||
**out = **in
|
||||
}
|
||||
out.Interval = in.Interval
|
||||
if in.KubeConfig != nil {
|
||||
in, out := &in.KubeConfig, &out.KubeConfig
|
||||
*out = new(meta.KubeConfigReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.DependsOn != nil {
|
||||
in, out := &in.DependsOn, &out.DependsOn
|
||||
*out = make([]meta.NamespacedObjectReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.MaxHistory != nil {
|
||||
in, out := &in.MaxHistory, &out.MaxHistory
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.PersistentClient != nil {
|
||||
in, out := &in.PersistentClient, &out.PersistentClient
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.DriftDetection != nil {
|
||||
in, out := &in.DriftDetection, &out.DriftDetection
|
||||
*out = new(DriftDetection)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Install != nil {
|
||||
in, out := &in.Install, &out.Install
|
||||
*out = new(Install)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Upgrade != nil {
|
||||
in, out := &in.Upgrade, &out.Upgrade
|
||||
*out = new(Upgrade)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Test != nil {
|
||||
in, out := &in.Test, &out.Test
|
||||
*out = new(Test)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Rollback != nil {
|
||||
in, out := &in.Rollback, &out.Rollback
|
||||
*out = new(Rollback)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Uninstall != nil {
|
||||
in, out := &in.Uninstall, &out.Uninstall
|
||||
*out = new(Uninstall)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ValuesFrom != nil {
|
||||
in, out := &in.ValuesFrom, &out.ValuesFrom
|
||||
*out = make([]ValuesReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = new(v1.JSON)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.PostRenderers != nil {
|
||||
in, out := &in.PostRenderers, &out.PostRenderers
|
||||
*out = make([]PostRenderer, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmReleaseSpec.
|
||||
func (in *HelmReleaseSpec) DeepCopy() *HelmReleaseSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmReleaseSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HelmReleaseStatus) DeepCopyInto(out *HelmReleaseStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]metav1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.History != nil {
|
||||
in, out := &in.History, &out.History
|
||||
*out = make(v2.Snapshots, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(v2.Snapshot)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
out.ReconcileRequestStatus = in.ReconcileRequestStatus
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmReleaseStatus.
|
||||
func (in *HelmReleaseStatus) DeepCopy() *HelmReleaseStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HelmReleaseStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *IgnoreRule) DeepCopyInto(out *IgnoreRule) {
|
||||
*out = *in
|
||||
if in.Paths != nil {
|
||||
in, out := &in.Paths, &out.Paths
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Target != nil {
|
||||
in, out := &in.Target, &out.Target
|
||||
*out = new(kustomize.Selector)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IgnoreRule.
|
||||
func (in *IgnoreRule) DeepCopy() *IgnoreRule {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(IgnoreRule)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Install) DeepCopyInto(out *Install) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Remediation != nil {
|
||||
in, out := &in.Remediation, &out.Remediation
|
||||
*out = new(InstallRemediation)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Install.
|
||||
func (in *Install) DeepCopy() *Install {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Install)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InstallRemediation) DeepCopyInto(out *InstallRemediation) {
|
||||
*out = *in
|
||||
if in.IgnoreTestFailures != nil {
|
||||
in, out := &in.IgnoreTestFailures, &out.IgnoreTestFailures
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.RemediateLastFailure != nil {
|
||||
in, out := &in.RemediateLastFailure, &out.RemediateLastFailure
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallRemediation.
|
||||
func (in *InstallRemediation) DeepCopy() *InstallRemediation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InstallRemediation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Kustomize) DeepCopyInto(out *Kustomize) {
|
||||
*out = *in
|
||||
if in.Patches != nil {
|
||||
in, out := &in.Patches, &out.Patches
|
||||
*out = make([]kustomize.Patch, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.PatchesStrategicMerge != nil {
|
||||
in, out := &in.PatchesStrategicMerge, &out.PatchesStrategicMerge
|
||||
*out = make([]v1.JSON, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.PatchesJSON6902 != nil {
|
||||
in, out := &in.PatchesJSON6902, &out.PatchesJSON6902
|
||||
*out = make([]kustomize.JSON6902Patch, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Images != nil {
|
||||
in, out := &in.Images, &out.Images
|
||||
*out = make([]kustomize.Image, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kustomize.
|
||||
func (in *Kustomize) DeepCopy() *Kustomize {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Kustomize)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PostRenderer) DeepCopyInto(out *PostRenderer) {
|
||||
*out = *in
|
||||
if in.Kustomize != nil {
|
||||
in, out := &in.Kustomize, &out.Kustomize
|
||||
*out = new(Kustomize)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostRenderer.
|
||||
func (in *PostRenderer) DeepCopy() *PostRenderer {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PostRenderer)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Rollback) DeepCopyInto(out *Rollback) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rollback.
|
||||
func (in *Rollback) DeepCopy() *Rollback {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Rollback)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Snapshot) DeepCopyInto(out *Snapshot) {
|
||||
*out = *in
|
||||
in.FirstDeployed.DeepCopyInto(&out.FirstDeployed)
|
||||
in.LastDeployed.DeepCopyInto(&out.LastDeployed)
|
||||
in.Deleted.DeepCopyInto(&out.Deleted)
|
||||
if in.TestHooks != nil {
|
||||
in, out := &in.TestHooks, &out.TestHooks
|
||||
*out = new(map[string]*TestHookStatus)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]*TestHookStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *TestHookStatus
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
inVal := (*in)[key]
|
||||
in, out := &inVal, &outVal
|
||||
*out = new(TestHookStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Snapshot.
|
||||
func (in *Snapshot) DeepCopy() *Snapshot {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Snapshot)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in Snapshots) DeepCopyInto(out *Snapshots) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(Snapshots, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(Snapshot)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Snapshots.
|
||||
func (in Snapshots) DeepCopy() Snapshots {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Snapshots)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Test) DeepCopyInto(out *Test) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Filters != nil {
|
||||
in, out := &in.Filters, &out.Filters
|
||||
*out = new([]Filter)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]Filter, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Test.
|
||||
func (in *Test) DeepCopy() *Test {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Test)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TestHookStatus) DeepCopyInto(out *TestHookStatus) {
|
||||
*out = *in
|
||||
in.LastStarted.DeepCopyInto(&out.LastStarted)
|
||||
in.LastCompleted.DeepCopyInto(&out.LastCompleted)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TestHookStatus.
|
||||
func (in *TestHookStatus) DeepCopy() *TestHookStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TestHookStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Uninstall) DeepCopyInto(out *Uninstall) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.DeletionPropagation != nil {
|
||||
in, out := &in.DeletionPropagation, &out.DeletionPropagation
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Uninstall.
|
||||
func (in *Uninstall) DeepCopy() *Uninstall {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Uninstall)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Upgrade) DeepCopyInto(out *Upgrade) {
|
||||
*out = *in
|
||||
if in.Timeout != nil {
|
||||
in, out := &in.Timeout, &out.Timeout
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.Remediation != nil {
|
||||
in, out := &in.Remediation, &out.Remediation
|
||||
*out = new(UpgradeRemediation)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Upgrade.
|
||||
func (in *Upgrade) DeepCopy() *Upgrade {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Upgrade)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpgradeRemediation) DeepCopyInto(out *UpgradeRemediation) {
|
||||
*out = *in
|
||||
if in.IgnoreTestFailures != nil {
|
||||
in, out := &in.IgnoreTestFailures, &out.IgnoreTestFailures
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.RemediateLastFailure != nil {
|
||||
in, out := &in.RemediateLastFailure, &out.RemediateLastFailure
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Strategy != nil {
|
||||
in, out := &in.Strategy, &out.Strategy
|
||||
*out = new(RemediationStrategy)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpgradeRemediation.
|
||||
func (in *UpgradeRemediation) DeepCopy() *UpgradeRemediation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpgradeRemediation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ValuesReference) DeepCopyInto(out *ValuesReference) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValuesReference.
|
||||
func (in *ValuesReference) DeepCopy() *ValuesReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ValuesReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -2,8 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
|||
kind: Kustomization
|
||||
namespace: helm-system
|
||||
resources:
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.6.0/source-controller.crds.yaml
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v1.6.0/source-controller.deployment.yaml
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v0.16.0/source-controller.crds.yaml
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v0.16.0/source-controller.deployment.yaml
|
||||
- ../crd
|
||||
- ../rbac
|
||||
- ../manager
|
||||
|
|
|
@ -18,10 +18,6 @@ spec:
|
|||
prometheus.io/port: "8080"
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 600
|
||||
securityContext:
|
||||
# Required for AWS IAM Role bindings
|
||||
# https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html
|
||||
fsGroup: 1337
|
||||
containers:
|
||||
- name: manager
|
||||
image: fluxcd/helm-controller
|
||||
|
@ -29,15 +25,9 @@ spec:
|
|||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http-prom
|
||||
protocol: TCP
|
||||
- containerPort: 9440
|
||||
name: healthz
|
||||
protocol: TCP
|
||||
|
|
|
@ -5,4 +5,4 @@ resources:
|
|||
images:
|
||||
- name: fluxcd/helm-controller
|
||||
newName: fluxcd/helm-controller
|
||||
newTag: v1.3.0
|
||||
newTag: v0.12.2
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: manager-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
|
@ -45,7 +47,6 @@ rules:
|
|||
- source.toolkit.fluxcd.io
|
||||
resources:
|
||||
- helmcharts
|
||||
- ocirepositories
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
|
@ -54,6 +55,5 @@ rules:
|
|||
- source.toolkit.fluxcd.io
|
||||
resources:
|
||||
- helmcharts/status
|
||||
- ocirepositories/status
|
||||
verbs:
|
||||
- get
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-ocirepository
|
||||
spec:
|
||||
interval: 5m
|
||||
chartRef:
|
||||
kind: OCIRepository
|
||||
name: podinfo
|
||||
test:
|
||||
enable: true
|
||||
values:
|
||||
replicaCount: 2
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-gitrepository
|
||||
|
@ -10,3 +10,9 @@ spec:
|
|||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: podinfo
|
||||
interval: 1m
|
||||
upgrade:
|
||||
remediation:
|
||||
remediateLastFailure: true
|
||||
test:
|
||||
enable: true
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-helmrepository
|
||||
|
@ -7,8 +7,13 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
upgrade:
|
||||
remediation:
|
||||
remediateLastFailure: true
|
||||
test:
|
||||
enable: true
|
|
@ -1,9 +0,0 @@
|
|||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: OCIRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
spec:
|
||||
interval: 1m
|
||||
url: oci://ghcr.io/stefanprodan/charts/podinfo
|
||||
ref:
|
||||
semver: 6.x
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: podinfo
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: podinfo
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: this
|
||||
|
@ -11,6 +11,6 @@ spec:
|
|||
{{- if .Values.branch }}
|
||||
branch: "{{ .Values.branch }}"
|
||||
{{- end}}
|
||||
{{- if .Values.tag }}
|
||||
{{- if .Values.branch }}
|
||||
tag: "{{ .Values.tag }}"
|
||||
{{- end}}
|
||||
{{- end}}
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: crds-upgrade-test
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: crds-upgrade-test
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: crds-upgrade-test
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: delete-ns
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: gotk-reconciler
|
||||
namespace: delete-ns
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: gotk-reconciler
|
||||
namespace: delete-ns
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- '*'
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: gotk-reconciler
|
||||
namespace: delete-ns
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: gotk-reconciler
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: gotk-reconciler
|
||||
namespace: delete-ns
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: delete-ns
|
||||
spec:
|
||||
interval: 1m
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: delete-ns
|
||||
spec:
|
||||
serviceAccountName: gotk-reconciler
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: 6.3.5
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: backend
|
||||
|
@ -7,7 +7,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: frontend
|
||||
|
@ -7,7 +7,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
|
|
@ -42,7 +42,7 @@ subjects:
|
|||
name: gotk-reconciler
|
||||
namespace: impersonation
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
|
@ -51,7 +51,7 @@ spec:
|
|||
interval: 1m
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo
|
||||
|
@ -62,12 +62,12 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: 6.3.5
|
||||
version: 5.0.3
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-fail
|
||||
|
@ -78,7 +78,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: 6.3.5
|
||||
version: 5.0.3
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: install-create-target-ns
|
||||
|
@ -9,7 +9,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: install-fail-remediate
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
install:
|
||||
remediation:
|
||||
remediateLastFailure: true
|
||||
uninstall:
|
||||
keepHistory: true
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: install-fail-retry
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
install:
|
||||
remediation:
|
||||
retries: 1
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: install-fail
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmChart
|
||||
metadata:
|
||||
name: podinfo-hc
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '6.2.1'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo-oci
|
||||
interval: 30s
|
||||
verify:
|
||||
provider: cosign
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-from-hc
|
||||
spec:
|
||||
chartRef:
|
||||
kind: HelmChart
|
||||
name: podinfo-hc
|
||||
interval: 30s
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
|
@ -1,25 +0,0 @@
|
|||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: OCIRepository
|
||||
metadata:
|
||||
name: podinfo-ocirepo
|
||||
spec:
|
||||
interval: 30s
|
||||
url: oci://ghcr.io/stefanprodan/charts/podinfo
|
||||
ref:
|
||||
tag: 6.6.0
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-from-ocirepo
|
||||
spec:
|
||||
chartRef:
|
||||
kind: OCIRepository
|
||||
name: podinfo-ocirepo
|
||||
interval: 30s
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: install-test-fail-ignore
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
test:
|
||||
enable: true
|
||||
ignoreFailures: true
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: install-test-fail
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
test:
|
||||
enable: true
|
||||
values:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-git
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo-oci
|
||||
spec:
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '6.2.1'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo-oci
|
||||
interval: 1m
|
||||
verify:
|
||||
provider: cosign
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: podinfo
|
||||
|
@ -7,7 +7,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: post-renderer-kustomize
|
||||
|
@ -7,7 +7,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <6.9.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
@ -16,20 +16,20 @@ spec:
|
|||
fullnameOverride: mypodinfo
|
||||
postRenderers:
|
||||
- kustomize:
|
||||
patches:
|
||||
- patch: |
|
||||
kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: mypodinfo
|
||||
labels:
|
||||
xxxx: yyyy
|
||||
patchesStrategicMerge:
|
||||
- kind: Deployment
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: mypodinfo
|
||||
labels:
|
||||
xxxx: yyyy
|
||||
patchesJson6902:
|
||||
- target:
|
||||
group: apps
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: mypodinfo
|
||||
patch: |
|
||||
- op: add
|
||||
path: /metadata/labels/yyyy
|
||||
value: xxxx
|
||||
patch:
|
||||
- op: add
|
||||
path: /metadata/labels/yyyy
|
||||
value: xxxx
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: podinfo-oci
|
||||
spec:
|
||||
interval: 1m
|
||||
url: oci://ghcr.io/stefanprodan/charts
|
||||
type: "oci"
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: status-defaults
|
||||
|
@ -7,7 +7,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: targetnamespace
|
||||
|
@ -7,7 +7,7 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail-remediate-uninstall
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail-remediate-uninstall
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
upgrade:
|
||||
remediation:
|
||||
remediateLastFailure: true
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail-remediate
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail-remediate
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
upgrade:
|
||||
remediation:
|
||||
remediateLastFailure: true
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail-retry
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail-retry
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
upgrade:
|
||||
remediation:
|
||||
retries: 1
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-fail
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: OCIRepository
|
||||
metadata:
|
||||
name: upgrade-from-ocirepo-source
|
||||
spec:
|
||||
interval: 30s
|
||||
url: oci://ghcr.io/stefanprodan/charts/podinfo
|
||||
ref:
|
||||
digest: "sha256:cdd538a0167e4b51152b71a477e51eb6737553510ce8797dbcc537e1342311bb"
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-from-ocirepo-source
|
||||
spec:
|
||||
chartRef:
|
||||
kind: OCIRepository
|
||||
name: upgrade-from-ocirepo-source
|
||||
interval: 30s
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: OCIRepository
|
||||
metadata:
|
||||
name: upgrade-from-ocirepo-source
|
||||
spec:
|
||||
interval: 30s
|
||||
url: oci://ghcr.io/stefanprodan/charts/podinfo
|
||||
ref:
|
||||
digest: "sha256:0cc9a8446c95009ef382f5eade883a67c257f77d50f84e78ecef2aac9428d1e5"
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-test-fail
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
values:
|
||||
resources:
|
||||
requests:
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: upgrade-test-fail
|
||||
spec:
|
||||
interval: 30s
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
test:
|
||||
enable: true
|
||||
values:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: helm.toolkit.fluxcd.io/v2beta2
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: valuesfrom
|
||||
|
@ -7,11 +7,11 @@ spec:
|
|||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
version: '>=6.0.0 <7.0.0'
|
||||
version: '>=4.0.0 <5.0.0'
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: podinfo
|
||||
interval: 10m
|
||||
interval: 1m
|
||||
valuesFrom:
|
||||
- kind: ConfigMap
|
||||
name: valuesfrom-config
|
||||
|
|
|
@ -0,0 +1,796 @@
|
|||
/*
|
||||
Copyright 2020 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 controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/hashicorp/go-retryablehttp"
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"helm.sh/helm/v3/pkg/storage/driver"
|
||||
"helm.sh/helm/v3/pkg/strvals"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/client-go/rest"
|
||||
kuberecorder "k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/tools/reference"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
"github.com/fluxcd/pkg/runtime/events"
|
||||
"github.com/fluxcd/pkg/runtime/metrics"
|
||||
"github.com/fluxcd/pkg/runtime/predicates"
|
||||
"github.com/fluxcd/pkg/runtime/transform"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
|
||||
v2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||
"github.com/fluxcd/helm-controller/internal/kube"
|
||||
"github.com/fluxcd/helm-controller/internal/runner"
|
||||
"github.com/fluxcd/helm-controller/internal/util"
|
||||
)
|
||||
|
||||
// +kubebuilder:rbac:groups=helm.toolkit.fluxcd.io,resources=helmreleases,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=helm.toolkit.fluxcd.io,resources=helmreleases/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=helm.toolkit.fluxcd.io,resources=helmreleases/finalizers,verbs=get;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=helmcharts,verbs=get;list;watch
|
||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=helmcharts/status,verbs=get
|
||||
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
|
||||
|
||||
// HelmReleaseReconciler reconciles a HelmRelease object
|
||||
type HelmReleaseReconciler struct {
|
||||
client.Client
|
||||
httpClient *retryablehttp.Client
|
||||
Config *rest.Config
|
||||
Scheme *runtime.Scheme
|
||||
requeueDependency time.Duration
|
||||
EventRecorder kuberecorder.EventRecorder
|
||||
ExternalEventRecorder *events.Recorder
|
||||
MetricsRecorder *metrics.Recorder
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) SetupWithManager(mgr ctrl.Manager, opts HelmReleaseReconcilerOptions) error {
|
||||
// Index the HelmRelease by the HelmChart references they point at
|
||||
if err := mgr.GetFieldIndexer().IndexField(context.TODO(), &v2.HelmRelease{}, v2.SourceIndexKey,
|
||||
func(o client.Object) []string {
|
||||
hr := o.(*v2.HelmRelease)
|
||||
return []string{
|
||||
fmt.Sprintf("%s/%s", hr.Spec.Chart.GetNamespace(hr.GetNamespace()), hr.GetHelmChartName()),
|
||||
}
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.requeueDependency = opts.DependencyRequeueInterval
|
||||
|
||||
// Configure the retryable http client used for fetching artifacts.
|
||||
// By default it retries 10 times within a 3.5 minutes window.
|
||||
httpClient := retryablehttp.NewClient()
|
||||
httpClient.RetryWaitMin = 5 * time.Second
|
||||
httpClient.RetryWaitMax = 30 * time.Second
|
||||
httpClient.RetryMax = opts.HTTPRetry
|
||||
httpClient.Logger = nil
|
||||
r.httpClient = httpClient
|
||||
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&v2.HelmRelease{}, builder.WithPredicates(
|
||||
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
|
||||
)).
|
||||
Watches(
|
||||
&source.Kind{Type: &sourcev1.HelmChart{}},
|
||||
handler.EnqueueRequestsFromMapFunc(r.requestsForHelmChartChange),
|
||||
builder.WithPredicates(SourceRevisionChangePredicate{}),
|
||||
).
|
||||
WithOptions(controller.Options{MaxConcurrentReconciles: opts.MaxConcurrentReconciles}).
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
// ConditionError represents an error with a status condition reason attached.
|
||||
type ConditionError struct {
|
||||
Reason string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (c ConditionError) Error() string {
|
||||
return c.Err.Error()
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
start := time.Now()
|
||||
log := logr.FromContext(ctx)
|
||||
|
||||
var hr v2.HelmRelease
|
||||
if err := r.Get(ctx, req.NamespacedName, &hr); err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
// record suspension metrics
|
||||
defer r.recordSuspension(ctx, hr)
|
||||
|
||||
// Add our finalizer if it does not exist
|
||||
if !controllerutil.ContainsFinalizer(&hr, v2.HelmReleaseFinalizer) {
|
||||
controllerutil.AddFinalizer(&hr, v2.HelmReleaseFinalizer)
|
||||
if err := r.Update(ctx, &hr); err != nil {
|
||||
log.Error(err, "unable to register finalizer")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
}
|
||||
|
||||
// Examine if the object is under deletion
|
||||
if !hr.ObjectMeta.DeletionTimestamp.IsZero() {
|
||||
return r.reconcileDelete(ctx, hr)
|
||||
}
|
||||
|
||||
// Return early if the HelmRelease is suspended.
|
||||
if hr.Spec.Suspend {
|
||||
log.Info("Reconciliation is suspended for this object")
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
hr, result, err := r.reconcile(ctx, hr)
|
||||
|
||||
// Update status after reconciliation.
|
||||
if updateStatusErr := r.patchStatus(ctx, &hr); updateStatusErr != nil {
|
||||
log.Error(updateStatusErr, "unable to update status after reconciliation")
|
||||
return ctrl.Result{Requeue: true}, updateStatusErr
|
||||
}
|
||||
|
||||
// Record ready status
|
||||
r.recordReadiness(ctx, hr)
|
||||
|
||||
// Log reconciliation duration
|
||||
durationMsg := fmt.Sprintf("reconcilation finished in %s", time.Now().Sub(start).String())
|
||||
if result.RequeueAfter > 0 {
|
||||
durationMsg = fmt.Sprintf("%s, next run in %s", durationMsg, result.RequeueAfter.String())
|
||||
}
|
||||
log.Info(durationMsg)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) reconcile(ctx context.Context, hr v2.HelmRelease) (v2.HelmRelease, ctrl.Result, error) {
|
||||
reconcileStart := time.Now()
|
||||
log := logr.FromContext(ctx)
|
||||
// Record the value of the reconciliation request, if any
|
||||
if v, ok := meta.ReconcileAnnotationValue(hr.GetAnnotations()); ok {
|
||||
hr.Status.SetLastHandledReconcileRequest(v)
|
||||
}
|
||||
|
||||
// Observe HelmRelease generation.
|
||||
if hr.Status.ObservedGeneration != hr.Generation {
|
||||
hr.Status.ObservedGeneration = hr.Generation
|
||||
hr = v2.HelmReleaseProgressing(hr)
|
||||
if updateStatusErr := r.patchStatus(ctx, &hr); updateStatusErr != nil {
|
||||
log.Error(updateStatusErr, "unable to update status after generation update")
|
||||
return hr, ctrl.Result{Requeue: true}, updateStatusErr
|
||||
}
|
||||
// Record progressing status
|
||||
r.recordReadiness(ctx, hr)
|
||||
}
|
||||
|
||||
// Record reconciliation duration
|
||||
if r.MetricsRecorder != nil {
|
||||
objRef, err := reference.GetReference(r.Scheme, &hr)
|
||||
if err != nil {
|
||||
return hr, ctrl.Result{Requeue: true}, err
|
||||
}
|
||||
defer r.MetricsRecorder.RecordDuration(*objRef, reconcileStart)
|
||||
}
|
||||
|
||||
// Reconcile chart based on the HelmChartTemplate
|
||||
hc, reconcileErr := r.reconcileChart(ctx, &hr)
|
||||
if reconcileErr != nil {
|
||||
msg := fmt.Sprintf("chart reconciliation failed: %s", reconcileErr.Error())
|
||||
r.event(ctx, hr, hr.Status.LastAttemptedRevision, events.EventSeverityError, msg)
|
||||
return v2.HelmReleaseNotReady(hr, v2.ArtifactFailedReason, msg), ctrl.Result{Requeue: true}, reconcileErr
|
||||
}
|
||||
|
||||
// Check chart readiness
|
||||
if hc.Generation != hc.Status.ObservedGeneration || !apimeta.IsStatusConditionTrue(hc.Status.Conditions, meta.ReadyCondition) {
|
||||
msg := fmt.Sprintf("HelmChart '%s/%s' is not ready", hc.GetNamespace(), hc.GetName())
|
||||
r.event(ctx, hr, hr.Status.LastAttemptedRevision, events.EventSeverityInfo, msg)
|
||||
log.Info(msg)
|
||||
// Do not requeue immediately, when the artifact is created
|
||||
// the watcher should trigger a reconciliation.
|
||||
return v2.HelmReleaseNotReady(hr, v2.ArtifactFailedReason, msg), ctrl.Result{RequeueAfter: hc.Spec.Interval.Duration}, nil
|
||||
}
|
||||
|
||||
// Check dependencies
|
||||
if len(hr.Spec.DependsOn) > 0 {
|
||||
if err := r.checkDependencies(hr); err != nil {
|
||||
msg := fmt.Sprintf("dependencies do not meet ready condition (%s), retrying in %s",
|
||||
err.Error(), r.requeueDependency.String())
|
||||
r.event(ctx, hr, hc.GetArtifact().Revision, events.EventSeverityInfo, msg)
|
||||
log.Info(msg)
|
||||
|
||||
// Exponential backoff would cause execution to be prolonged too much,
|
||||
// instead we requeue on a fixed interval.
|
||||
return v2.HelmReleaseNotReady(hr,
|
||||
meta.DependencyNotReadyReason, err.Error()), ctrl.Result{RequeueAfter: r.requeueDependency}, nil
|
||||
}
|
||||
log.Info("all dependencies are ready, proceeding with release")
|
||||
}
|
||||
|
||||
// Compose values
|
||||
values, err := r.composeValues(ctx, hr)
|
||||
if err != nil {
|
||||
r.event(ctx, hr, hr.Status.LastAttemptedRevision, events.EventSeverityError, err.Error())
|
||||
return v2.HelmReleaseNotReady(hr, v2.InitFailedReason, err.Error()), ctrl.Result{Requeue: true}, nil
|
||||
}
|
||||
|
||||
// Load chart from artifact
|
||||
chart, err := r.loadHelmChart(hc)
|
||||
if err != nil {
|
||||
r.event(ctx, hr, hr.Status.LastAttemptedRevision, events.EventSeverityError, err.Error())
|
||||
return v2.HelmReleaseNotReady(hr, v2.ArtifactFailedReason, err.Error()), ctrl.Result{Requeue: true}, nil
|
||||
}
|
||||
|
||||
// Reconcile Helm release
|
||||
reconciledHr, reconcileErr := r.reconcileRelease(ctx, *hr.DeepCopy(), chart, values)
|
||||
if reconcileErr != nil {
|
||||
r.event(ctx, hr, hc.GetArtifact().Revision, events.EventSeverityError,
|
||||
fmt.Sprintf("reconciliation failed: %s", reconcileErr.Error()))
|
||||
}
|
||||
return reconciledHr, ctrl.Result{RequeueAfter: hr.Spec.Interval.Duration}, reconcileErr
|
||||
}
|
||||
|
||||
type HelmReleaseReconcilerOptions struct {
|
||||
MaxConcurrentReconciles int
|
||||
HTTPRetry int
|
||||
DependencyRequeueInterval time.Duration
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) reconcileRelease(ctx context.Context,
|
||||
hr v2.HelmRelease, chart *chart.Chart, values chartutil.Values) (v2.HelmRelease, error) {
|
||||
log := logr.FromContext(ctx)
|
||||
|
||||
// Initialize Helm action runner
|
||||
getter, err := r.getRESTClientGetter(ctx, hr)
|
||||
if err != nil {
|
||||
return v2.HelmReleaseNotReady(hr, v2.InitFailedReason, err.Error()), err
|
||||
}
|
||||
run, err := runner.NewRunner(getter, hr.GetStorageNamespace(), log)
|
||||
if err != nil {
|
||||
return v2.HelmReleaseNotReady(hr, v2.InitFailedReason, "failed to initialize Helm action runner"), err
|
||||
}
|
||||
|
||||
// Determine last release revision.
|
||||
rel, observeLastReleaseErr := run.ObserveLastRelease(hr)
|
||||
if observeLastReleaseErr != nil {
|
||||
err = fmt.Errorf("failed to get last release revision: %w", observeLastReleaseErr)
|
||||
return v2.HelmReleaseNotReady(hr, v2.GetLastReleaseFailedReason, "failed to get last release revision"), err
|
||||
}
|
||||
|
||||
// Register the current release attempt.
|
||||
revision := chart.Metadata.Version
|
||||
releaseRevision := util.ReleaseRevision(rel)
|
||||
valuesChecksum := util.ValuesChecksum(values)
|
||||
hr, hasNewState := v2.HelmReleaseAttempted(hr, revision, releaseRevision, valuesChecksum)
|
||||
if hasNewState {
|
||||
hr = v2.HelmReleaseProgressing(hr)
|
||||
if updateStatusErr := r.patchStatus(ctx, &hr); updateStatusErr != nil {
|
||||
log.Error(updateStatusErr, "unable to update status after state update")
|
||||
return hr, updateStatusErr
|
||||
}
|
||||
// Record progressing status
|
||||
r.recordReadiness(ctx, hr)
|
||||
}
|
||||
|
||||
// Check status of any previous release attempt.
|
||||
released := apimeta.FindStatusCondition(hr.Status.Conditions, v2.ReleasedCondition)
|
||||
if released != nil {
|
||||
switch released.Status {
|
||||
// Succeed if the previous release attempt succeeded.
|
||||
case metav1.ConditionTrue:
|
||||
return v2.HelmReleaseReady(hr), nil
|
||||
case metav1.ConditionFalse:
|
||||
// Fail if the previous release attempt remediation failed.
|
||||
remediated := apimeta.FindStatusCondition(hr.Status.Conditions, v2.RemediatedCondition)
|
||||
if remediated != nil && remediated.Status == metav1.ConditionFalse {
|
||||
err = fmt.Errorf("previous release attempt remediation failed")
|
||||
return v2.HelmReleaseNotReady(hr, remediated.Reason, remediated.Message), err
|
||||
}
|
||||
}
|
||||
|
||||
// Fail if install retries are exhausted.
|
||||
if hr.Spec.GetInstall().GetRemediation().RetriesExhausted(hr) {
|
||||
err = fmt.Errorf("install retries exhausted")
|
||||
return v2.HelmReleaseNotReady(hr, released.Reason, err.Error()), err
|
||||
}
|
||||
|
||||
// Fail if there is a release and upgrade retries are exhausted.
|
||||
// This avoids failing after an upgrade uninstall remediation strategy.
|
||||
if rel != nil && hr.Spec.GetUpgrade().GetRemediation().RetriesExhausted(hr) {
|
||||
err = fmt.Errorf("upgrade retries exhausted")
|
||||
return v2.HelmReleaseNotReady(hr, released.Reason, err.Error()), err
|
||||
}
|
||||
}
|
||||
|
||||
// Deploy the release.
|
||||
var deployAction v2.DeploymentAction
|
||||
if rel == nil {
|
||||
r.event(ctx, hr, revision, events.EventSeverityInfo, "Helm install has started")
|
||||
deployAction = hr.Spec.GetInstall()
|
||||
rel, err = run.Install(hr, chart, values)
|
||||
err = r.handleHelmActionResult(ctx, &hr, revision, err, deployAction.GetDescription(),
|
||||
v2.ReleasedCondition, v2.InstallSucceededReason, v2.InstallFailedReason)
|
||||
} else {
|
||||
r.event(ctx, hr, revision, events.EventSeverityInfo, "Helm upgrade has started")
|
||||
deployAction = hr.Spec.GetUpgrade()
|
||||
rel, err = run.Upgrade(hr, chart, values)
|
||||
err = r.handleHelmActionResult(ctx, &hr, revision, err, deployAction.GetDescription(),
|
||||
v2.ReleasedCondition, v2.UpgradeSucceededReason, v2.UpgradeFailedReason)
|
||||
}
|
||||
remediation := deployAction.GetRemediation()
|
||||
|
||||
// If there is a new release revision...
|
||||
if util.ReleaseRevision(rel) > releaseRevision {
|
||||
// Ensure release is not marked remediated.
|
||||
apimeta.RemoveStatusCondition(&hr.Status.Conditions, v2.RemediatedCondition)
|
||||
|
||||
// If new release revision is successful and tests are enabled, run them.
|
||||
if err == nil && hr.Spec.GetTest().Enable {
|
||||
_, testErr := run.Test(hr)
|
||||
testErr = r.handleHelmActionResult(ctx, &hr, revision, testErr, "test",
|
||||
v2.TestSuccessCondition, v2.TestSucceededReason, v2.TestFailedReason)
|
||||
|
||||
// Propagate any test error if not marked ignored.
|
||||
if testErr != nil && !remediation.MustIgnoreTestFailures(hr.Spec.GetTest().IgnoreFailures) {
|
||||
testsPassing := apimeta.FindStatusCondition(hr.Status.Conditions, v2.TestSuccessCondition)
|
||||
meta.SetResourceCondition(&hr, v2.ReleasedCondition, metav1.ConditionFalse, testsPassing.Reason, testsPassing.Message)
|
||||
err = testErr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// Increment failure count for deployment action.
|
||||
remediation.IncrementFailureCount(&hr)
|
||||
// Remediate deployment failure if necessary.
|
||||
if !remediation.RetriesExhausted(hr) || remediation.MustRemediateLastFailure() {
|
||||
if util.ReleaseRevision(rel) <= releaseRevision {
|
||||
log.Info(fmt.Sprintf("skipping remediation, no new release revision created"))
|
||||
} else {
|
||||
var remediationErr error
|
||||
switch remediation.GetStrategy() {
|
||||
case v2.RollbackRemediationStrategy:
|
||||
rollbackErr := run.Rollback(hr)
|
||||
remediationErr = r.handleHelmActionResult(ctx, &hr, revision, rollbackErr, "rollback",
|
||||
v2.RemediatedCondition, v2.RollbackSucceededReason, v2.RollbackFailedReason)
|
||||
case v2.UninstallRemediationStrategy:
|
||||
uninstallErr := run.Uninstall(hr)
|
||||
remediationErr = r.handleHelmActionResult(ctx, &hr, revision, uninstallErr, "uninstall",
|
||||
v2.RemediatedCondition, v2.UninstallSucceededReason, v2.UninstallFailedReason)
|
||||
}
|
||||
if remediationErr != nil {
|
||||
err = remediationErr
|
||||
}
|
||||
}
|
||||
|
||||
// Determine release after remediation.
|
||||
rel, observeLastReleaseErr = run.ObserveLastRelease(hr)
|
||||
if observeLastReleaseErr != nil {
|
||||
err = &ConditionError{
|
||||
Reason: v2.GetLastReleaseFailedReason,
|
||||
Err: errors.New("failed to get last release revision after remediation"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr.Status.LastReleaseRevision = util.ReleaseRevision(rel)
|
||||
|
||||
if err != nil {
|
||||
reason := meta.ReconciliationFailedReason
|
||||
if condErr := (*ConditionError)(nil); errors.As(err, &condErr) {
|
||||
reason = condErr.Reason
|
||||
}
|
||||
return v2.HelmReleaseNotReady(hr, reason, err.Error()), err
|
||||
}
|
||||
return v2.HelmReleaseReady(hr), nil
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) checkDependencies(hr v2.HelmRelease) error {
|
||||
for _, d := range hr.Spec.DependsOn {
|
||||
if d.Namespace == "" {
|
||||
d.Namespace = hr.GetNamespace()
|
||||
}
|
||||
dName := types.NamespacedName(d)
|
||||
var dHr v2.HelmRelease
|
||||
err := r.Get(context.Background(), dName, &dHr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get '%s' dependency: %w", dName, err)
|
||||
}
|
||||
|
||||
if len(dHr.Status.Conditions) == 0 || dHr.Generation != dHr.Status.ObservedGeneration {
|
||||
return fmt.Errorf("dependency '%s' is not ready", dName)
|
||||
}
|
||||
|
||||
if !apimeta.IsStatusConditionTrue(dHr.Status.Conditions, meta.ReadyCondition) {
|
||||
return fmt.Errorf("dependency '%s' is not ready", dName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) getRESTClientGetter(ctx context.Context, hr v2.HelmRelease) (genericclioptions.RESTClientGetter, error) {
|
||||
if hr.Spec.KubeConfig == nil {
|
||||
// impersonate service account if specified
|
||||
if hr.Spec.ServiceAccountName != "" {
|
||||
token, err := r.getServiceAccountToken(ctx, hr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not impersonate ServiceAccount '%s': %w", hr.Spec.ServiceAccountName, err)
|
||||
}
|
||||
|
||||
config := *r.Config
|
||||
config.BearerToken = token
|
||||
return kube.NewInClusterRESTClientGetter(&config, hr.GetReleaseNamespace()), nil
|
||||
}
|
||||
|
||||
return kube.NewInClusterRESTClientGetter(r.Config, hr.GetReleaseNamespace()), nil
|
||||
}
|
||||
secretName := types.NamespacedName{
|
||||
Namespace: hr.GetNamespace(),
|
||||
Name: hr.Spec.KubeConfig.SecretRef.Name,
|
||||
}
|
||||
var secret corev1.Secret
|
||||
if err := r.Get(ctx, secretName, &secret); err != nil {
|
||||
return nil, fmt.Errorf("could not find KubeConfig secret '%s': %w", secretName, err)
|
||||
}
|
||||
|
||||
var kubeConfig []byte
|
||||
for k, _ := range secret.Data {
|
||||
if k == "value" || k == "value.yaml" {
|
||||
kubeConfig = secret.Data[k]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(kubeConfig) == 0 {
|
||||
return nil, fmt.Errorf("KubeConfig secret '%s' does not contain a 'value' key", secretName)
|
||||
}
|
||||
return kube.NewMemoryRESTClientGetter(kubeConfig, hr.GetReleaseNamespace()), nil
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) getServiceAccountToken(ctx context.Context, hr v2.HelmRelease) (string, error) {
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: hr.Namespace,
|
||||
Name: hr.Spec.ServiceAccountName,
|
||||
}
|
||||
|
||||
var serviceAccount corev1.ServiceAccount
|
||||
err := r.Client.Get(ctx, namespacedName, &serviceAccount)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
secretName := types.NamespacedName{
|
||||
Namespace: hr.Namespace,
|
||||
Name: hr.Spec.ServiceAccountName,
|
||||
}
|
||||
|
||||
for _, secret := range serviceAccount.Secrets {
|
||||
if strings.HasPrefix(secret.Name, fmt.Sprintf("%s-token", serviceAccount.Name)) {
|
||||
secretName.Name = secret.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var secret corev1.Secret
|
||||
err = r.Client.Get(ctx, secretName, &secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var token string
|
||||
if data, ok := secret.Data["token"]; ok {
|
||||
token = string(data)
|
||||
} else {
|
||||
return "", fmt.Errorf("the service account secret '%s' does not containt a token", secretName.String())
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// composeValues attempts to resolve all v2beta1.ValuesReference resources
|
||||
// and merges them as defined. Referenced resources are only retrieved once
|
||||
// to ensure a single version is taken into account during the merge.
|
||||
func (r *HelmReleaseReconciler) composeValues(ctx context.Context, hr v2.HelmRelease) (chartutil.Values, error) {
|
||||
result := chartutil.Values{}
|
||||
|
||||
configMaps := make(map[string]*corev1.ConfigMap)
|
||||
secrets := make(map[string]*corev1.Secret)
|
||||
|
||||
for _, v := range hr.Spec.ValuesFrom {
|
||||
namespacedName := types.NamespacedName{Namespace: hr.Namespace, Name: v.Name}
|
||||
var valuesData []byte
|
||||
|
||||
switch v.Kind {
|
||||
case "ConfigMap":
|
||||
resource, ok := configMaps[namespacedName.String()]
|
||||
if !ok {
|
||||
// The resource may not exist, but we want to act on a single version
|
||||
// of the resource in case the values reference is marked as optional.
|
||||
configMaps[namespacedName.String()] = nil
|
||||
|
||||
resource = &corev1.ConfigMap{}
|
||||
if err := r.Get(ctx, namespacedName, resource); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
if v.Optional {
|
||||
(logr.FromContext(ctx)).
|
||||
Info(fmt.Sprintf("could not find optional %s '%s'", v.Kind, namespacedName))
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("could not find %s '%s'", v.Kind, namespacedName)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
configMaps[namespacedName.String()] = resource
|
||||
}
|
||||
if resource == nil {
|
||||
if v.Optional {
|
||||
(logr.FromContext(ctx)).Info(fmt.Sprintf("could not find optional %s '%s'", v.Kind, namespacedName))
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("could not find %s '%s'", v.Kind, namespacedName)
|
||||
}
|
||||
if data, ok := resource.Data[v.GetValuesKey()]; !ok {
|
||||
return nil, fmt.Errorf("missing key '%s' in %s '%s'", v.GetValuesKey(), v.Kind, namespacedName)
|
||||
} else {
|
||||
valuesData = []byte(data)
|
||||
}
|
||||
case "Secret":
|
||||
resource, ok := secrets[namespacedName.String()]
|
||||
if !ok {
|
||||
// The resource may not exist, but we want to act on a single version
|
||||
// of the resource in case the values reference is marked as optional.
|
||||
secrets[namespacedName.String()] = nil
|
||||
|
||||
resource = &corev1.Secret{}
|
||||
if err := r.Get(ctx, namespacedName, resource); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
if v.Optional {
|
||||
(logr.FromContext(ctx)).
|
||||
Info(fmt.Sprintf("could not find optional %s '%s'", v.Kind, namespacedName))
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("could not find %s '%s'", v.Kind, namespacedName)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
secrets[namespacedName.String()] = resource
|
||||
}
|
||||
if resource == nil {
|
||||
if v.Optional {
|
||||
(logr.FromContext(ctx)).Info(fmt.Sprintf("could not find optional %s '%s'", v.Kind, namespacedName))
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("could not find %s '%s'", v.Kind, namespacedName)
|
||||
}
|
||||
if data, ok := resource.Data[v.GetValuesKey()]; !ok {
|
||||
return nil, fmt.Errorf("missing key '%s' in %s '%s'", v.GetValuesKey(), v.Kind, namespacedName)
|
||||
} else {
|
||||
valuesData = data
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported ValuesReference kind '%s'", v.Kind)
|
||||
}
|
||||
switch v.TargetPath {
|
||||
case "":
|
||||
values, err := chartutil.ReadValues(valuesData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read values from key '%s' in %s '%s': %w", v.GetValuesKey(), v.Kind, namespacedName, err)
|
||||
}
|
||||
result = transform.MergeMaps(result, values)
|
||||
default:
|
||||
// TODO(hidde): this is a bit of hack, as it mimics the way the option string is passed
|
||||
// to Helm from a CLI perspective. Given the parser is however not publicly accessible
|
||||
// while it contains all logic around parsing the target path, it is a fair trade-off.
|
||||
stringValuesData := string(valuesData)
|
||||
const singleQuote = "'"
|
||||
const doubleQuote = "\""
|
||||
var err error
|
||||
if (strings.HasPrefix(stringValuesData, singleQuote) && strings.HasSuffix(stringValuesData, singleQuote)) || (strings.HasPrefix(stringValuesData, doubleQuote) && strings.HasSuffix(stringValuesData, doubleQuote)) {
|
||||
stringValuesData = strings.Trim(stringValuesData, singleQuote+doubleQuote)
|
||||
singleValue := v.TargetPath + "=" + stringValuesData
|
||||
err = strvals.ParseIntoString(singleValue, result)
|
||||
} else {
|
||||
singleValue := v.TargetPath + "=" + stringValuesData
|
||||
err = strvals.ParseInto(singleValue, result)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to merge value from key '%s' in %s '%s' into target path '%s': %w", v.GetValuesKey(), v.Kind, namespacedName, v.TargetPath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return transform.MergeMaps(result, hr.GetValues()), nil
|
||||
}
|
||||
|
||||
// reconcileDelete deletes the v1beta1.HelmChart of the v2beta1.HelmRelease,
|
||||
// and uninstalls the Helm release if the resource has not been suspended.
|
||||
func (r *HelmReleaseReconciler) reconcileDelete(ctx context.Context, hr v2.HelmRelease) (ctrl.Result, error) {
|
||||
r.recordReadiness(ctx, hr)
|
||||
|
||||
// Delete the HelmChart that belongs to this resource.
|
||||
if err := r.deleteHelmChart(ctx, &hr); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// Only uninstall the Helm Release if the resource is not suspended.
|
||||
if !hr.Spec.Suspend {
|
||||
getter, err := r.getRESTClientGetter(ctx, hr)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
run, err := runner.NewRunner(getter, hr.GetStorageNamespace(), logr.FromContext(ctx))
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
if err := run.Uninstall(hr); err != nil && !errors.Is(err, driver.ErrReleaseNotFound) {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
logr.FromContext(ctx).Info("uninstalled Helm release for deleted resource")
|
||||
|
||||
} else {
|
||||
logr.FromContext(ctx).Info("skipping Helm uninstall for suspended resource")
|
||||
}
|
||||
|
||||
// Remove our finalizer from the list and update it.
|
||||
controllerutil.RemoveFinalizer(&hr, v2.HelmReleaseFinalizer)
|
||||
if err := r.Update(ctx, &hr); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) handleHelmActionResult(ctx context.Context,
|
||||
hr *v2.HelmRelease, revision string, err error, action string, condition string, succeededReason string, failedReason string) error {
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Helm %s failed: %w", action, err)
|
||||
msg := err.Error()
|
||||
if actionErr := (*runner.ActionError)(nil); errors.As(err, &actionErr) {
|
||||
msg = msg + "\n\nLast Helm logs:\n\n" + actionErr.CapturedLogs
|
||||
}
|
||||
meta.SetResourceCondition(hr, condition, metav1.ConditionFalse, failedReason, msg)
|
||||
r.event(ctx, *hr, revision, events.EventSeverityError, msg)
|
||||
return &ConditionError{Reason: failedReason, Err: err}
|
||||
} else {
|
||||
msg := fmt.Sprintf("Helm %s succeeded", action)
|
||||
meta.SetResourceCondition(hr, condition, metav1.ConditionTrue, succeededReason, msg)
|
||||
r.event(ctx, *hr, revision, events.EventSeverityInfo, msg)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) patchStatus(ctx context.Context, hr *v2.HelmRelease) error {
|
||||
key := client.ObjectKeyFromObject(hr)
|
||||
latest := &v2.HelmRelease{}
|
||||
if err := r.Client.Get(ctx, key, latest); err != nil {
|
||||
return err
|
||||
}
|
||||
return r.Client.Status().Patch(ctx, hr, client.MergeFrom(latest))
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) requestsForHelmChartChange(o client.Object) []reconcile.Request {
|
||||
hc, ok := o.(*sourcev1.HelmChart)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Expected a HelmChart, got %T", o))
|
||||
}
|
||||
// If we do not have an artifact, we have no requests to make
|
||||
if hc.GetArtifact() == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
var list v2.HelmReleaseList
|
||||
if err := r.List(ctx, &list, client.MatchingFields{
|
||||
v2.SourceIndexKey: client.ObjectKeyFromObject(hc).String(),
|
||||
}); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var reqs []reconcile.Request
|
||||
for _, i := range list.Items {
|
||||
// If the revision of the artifact equals to the last attempted revision,
|
||||
// we should not make a request for this HelmRelease
|
||||
if hc.GetArtifact().Revision == i.Status.LastAttemptedRevision {
|
||||
continue
|
||||
}
|
||||
reqs = append(reqs, reconcile.Request{NamespacedName: client.ObjectKeyFromObject(&i)})
|
||||
}
|
||||
return reqs
|
||||
}
|
||||
|
||||
// event emits a Kubernetes event and forwards the event to notification controller if configured.
|
||||
func (r *HelmReleaseReconciler) event(ctx context.Context, hr v2.HelmRelease, revision, severity, msg string) {
|
||||
r.EventRecorder.Event(&hr, "Normal", severity, msg)
|
||||
objRef, err := reference.GetReference(r.Scheme, &hr)
|
||||
if err != nil {
|
||||
logr.FromContext(ctx).Error(err, "unable to send event")
|
||||
return
|
||||
}
|
||||
|
||||
if r.ExternalEventRecorder != nil {
|
||||
var meta map[string]string
|
||||
if revision != "" {
|
||||
meta = map[string]string{"revision": revision}
|
||||
}
|
||||
if err := r.ExternalEventRecorder.Eventf(*objRef, meta, severity, severity, msg); err != nil {
|
||||
logr.FromContext(ctx).Error(err, "unable to send event")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) recordSuspension(ctx context.Context, hr v2.HelmRelease) {
|
||||
if r.MetricsRecorder == nil {
|
||||
return
|
||||
}
|
||||
log := logr.FromContext(ctx)
|
||||
|
||||
objRef, err := reference.GetReference(r.Scheme, &hr)
|
||||
if err != nil {
|
||||
log.Error(err, "unable to record suspended metric")
|
||||
return
|
||||
}
|
||||
|
||||
if !hr.DeletionTimestamp.IsZero() {
|
||||
r.MetricsRecorder.RecordSuspend(*objRef, false)
|
||||
} else {
|
||||
r.MetricsRecorder.RecordSuspend(*objRef, hr.Spec.Suspend)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *HelmReleaseReconciler) recordReadiness(ctx context.Context, hr v2.HelmRelease) {
|
||||
if r.MetricsRecorder == nil {
|
||||
return
|
||||
}
|
||||
|
||||
objRef, err := reference.GetReference(r.Scheme, &hr)
|
||||
if err != nil {
|
||||
logr.FromContext(ctx).Error(err, "unable to record readiness metric")
|
||||
return
|
||||
}
|
||||
if rc := apimeta.FindStatusCondition(hr.Status.Conditions, meta.ReadyCondition); rc != nil {
|
||||
r.MetricsRecorder.RecordCondition(*objRef, *rc, !hr.DeletionTimestamp.IsZero())
|
||||
} else {
|
||||
r.MetricsRecorder.RecordCondition(*objRef, metav1.Condition{
|
||||
Type: meta.ReadyCondition,
|
||||
Status: metav1.ConditionUnknown,
|
||||
}, !hr.DeletionTimestamp.IsZero())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
Copyright 2020 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 controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/hashicorp/go-retryablehttp"
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
"helm.sh/helm/v3/pkg/chart/loader"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
|
||||
v2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||
)
|
||||
|
||||
func (r *HelmReleaseReconciler) reconcileChart(ctx context.Context, hr *v2.HelmRelease) (*sourcev1.HelmChart, error) {
|
||||
chartName := types.NamespacedName{
|
||||
Namespace: hr.Spec.Chart.GetNamespace(hr.Namespace),
|
||||
Name: hr.GetHelmChartName(),
|
||||
}
|
||||
|
||||
// Garbage collect the previous HelmChart if the namespace named changed.
|
||||
if hr.Status.HelmChart != "" && hr.Status.HelmChart != chartName.String() {
|
||||
if err := r.deleteHelmChart(ctx, hr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Continue with the reconciliation of the current template.
|
||||
var helmChart sourcev1.HelmChart
|
||||
err := r.Client.Get(ctx, chartName, &helmChart)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
hc := buildHelmChartFromTemplate(hr)
|
||||
switch {
|
||||
case apierrors.IsNotFound(err):
|
||||
if err = r.Client.Create(ctx, hc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hr.Status.HelmChart = chartName.String()
|
||||
return hc, nil
|
||||
case helmChartRequiresUpdate(hr, &helmChart):
|
||||
logr.FromContext(ctx).Info("chart diverged from template", strings.ToLower(sourcev1.HelmChartKind), chartName.String())
|
||||
helmChart.Spec = hc.Spec
|
||||
if err = r.Client.Update(ctx, &helmChart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hr.Status.HelmChart = chartName.String()
|
||||
}
|
||||
return &helmChart, nil
|
||||
}
|
||||
|
||||
// getHelmChart retrieves the v1beta1.HelmChart for the given
|
||||
// v2beta1.HelmRelease using the name that is advertised in the status
|
||||
// object. It returns the v1beta1.HelmChart, or an error.
|
||||
func (r *HelmReleaseReconciler) getHelmChart(ctx context.Context, hr *v2.HelmRelease) (*sourcev1.HelmChart, error) {
|
||||
namespace, name := hr.Status.GetHelmChart()
|
||||
hc := &sourcev1.HelmChart{}
|
||||
if err := r.Client.Get(ctx, types.NamespacedName{Namespace: namespace, Name: name}, hc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hc, nil
|
||||
}
|
||||
|
||||
// loadHelmChart attempts to download the artifact from the provided source,
|
||||
// loads it into a chart.Chart, and removes the downloaded artifact.
|
||||
// It returns the loaded chart.Chart on success, or an error.
|
||||
func (r *HelmReleaseReconciler) loadHelmChart(source *sourcev1.HelmChart) (*chart.Chart, error) {
|
||||
f, err := ioutil.TempFile("", fmt.Sprintf("%s-%s-*.tgz", source.GetNamespace(), source.GetName()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
artifactURL := source.GetArtifact().URL
|
||||
if hostname := os.Getenv("SOURCE_CONTROLLER_LOCALHOST"); hostname != "" {
|
||||
u, err := url.Parse(artifactURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.Host = hostname
|
||||
artifactURL = u.String()
|
||||
}
|
||||
|
||||
req, err := retryablehttp.NewRequest(http.MethodGet, artifactURL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create a new request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := r.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to download artifact, error: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("artifact '%s' download failed (status code: %s)", source.GetArtifact().URL, resp.Status)
|
||||
}
|
||||
|
||||
if _, err = io.Copy(f, resp.Body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return loader.Load(f.Name())
|
||||
}
|
||||
|
||||
// deleteHelmChart deletes the v1beta1.HelmChart of the v2beta1.HelmRelease.
|
||||
func (r *HelmReleaseReconciler) deleteHelmChart(ctx context.Context, hr *v2.HelmRelease) error {
|
||||
if hr.Status.HelmChart == "" {
|
||||
return nil
|
||||
}
|
||||
var hc sourcev1.HelmChart
|
||||
chartNS, chartName := hr.Status.GetHelmChart()
|
||||
err := r.Client.Get(ctx, types.NamespacedName{Namespace: chartNS, Name: chartName}, &hc)
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
hr.Status.HelmChart = ""
|
||||
return nil
|
||||
}
|
||||
err = fmt.Errorf("failed to delete HelmChart '%s': %w", hr.Status.HelmChart, err)
|
||||
return err
|
||||
}
|
||||
if err = r.Client.Delete(ctx, &hc); err != nil {
|
||||
err = fmt.Errorf("failed to delete HelmChart '%s': %w", hr.Status.HelmChart, err)
|
||||
return err
|
||||
}
|
||||
// Truncate the chart reference in the status object.
|
||||
hr.Status.HelmChart = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildHelmChartFromTemplate builds a v1beta1.HelmChart from the
|
||||
// v2beta1.HelmChartTemplate of the given v2beta1.HelmRelease.
|
||||
func buildHelmChartFromTemplate(hr *v2.HelmRelease) *sourcev1.HelmChart {
|
||||
template := hr.Spec.Chart
|
||||
return &sourcev1.HelmChart{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: hr.GetHelmChartName(),
|
||||
Namespace: hr.Spec.Chart.GetNamespace(hr.Namespace),
|
||||
},
|
||||
Spec: sourcev1.HelmChartSpec{
|
||||
Chart: template.Spec.Chart,
|
||||
Version: template.Spec.Version,
|
||||
SourceRef: sourcev1.LocalHelmChartSourceReference{
|
||||
Name: template.Spec.SourceRef.Name,
|
||||
Kind: template.Spec.SourceRef.Kind,
|
||||
},
|
||||
Interval: template.GetInterval(hr.Spec.Interval),
|
||||
ReconcileStrategy: template.Spec.ReconcileStrategy,
|
||||
ValuesFiles: template.Spec.ValuesFiles,
|
||||
ValuesFile: template.Spec.ValuesFile,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// helmChartRequiresUpdate compares the v2beta1.HelmChartTemplate of the
|
||||
// v2beta1.HelmRelease to the given v1beta1.HelmChart to determine if an
|
||||
// update is required.
|
||||
func helmChartRequiresUpdate(hr *v2.HelmRelease, chart *sourcev1.HelmChart) bool {
|
||||
template := hr.Spec.Chart
|
||||
switch {
|
||||
case template.Spec.Chart != chart.Spec.Chart:
|
||||
return true
|
||||
// TODO(hidde): remove emptiness checks on next MINOR version
|
||||
case template.Spec.Version == "" && chart.Spec.Version != "*",
|
||||
template.Spec.Version != "" && template.Spec.Version != chart.Spec.Version:
|
||||
return true
|
||||
case template.Spec.SourceRef.Name != chart.Spec.SourceRef.Name:
|
||||
return true
|
||||
case template.Spec.SourceRef.Kind != chart.Spec.SourceRef.Kind:
|
||||
return true
|
||||
case template.GetInterval(hr.Spec.Interval) != chart.Spec.Interval:
|
||||
return true
|
||||
case template.Spec.ReconcileStrategy != chart.Spec.ReconcileStrategy:
|
||||
return true
|
||||
case !reflect.DeepEqual(template.Spec.ValuesFiles, chart.Spec.ValuesFiles):
|
||||
return true
|
||||
case template.Spec.ValuesFile != chart.Spec.ValuesFile:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
Copyright 2020 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 controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"github.com/go-logr/logr"
|
||||
. "github.com/onsi/gomega"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
v2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||
)
|
||||
|
||||
func TestHelmReleaseReconciler_reconcileChart(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
hr *v2.HelmRelease
|
||||
hc *sourcev1.HelmChart
|
||||
expectHelmChartStatus string
|
||||
expectGC bool
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "new HelmChart",
|
||||
hr: &v2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v2.HelmReleaseSpec{
|
||||
Interval: metav1.Duration{Duration: time.Minute},
|
||||
Chart: v2.HelmChartTemplate{
|
||||
Spec: v2.HelmChartTemplateSpec{
|
||||
Chart: "chart",
|
||||
SourceRef: v2.CrossNamespaceObjectReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
hc: nil,
|
||||
expectHelmChartStatus: "default/default-test-release",
|
||||
},
|
||||
{
|
||||
name: "existing HelmChart",
|
||||
hr: &v2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v2.HelmReleaseSpec{
|
||||
Interval: metav1.Duration{Duration: time.Minute},
|
||||
Chart: v2.HelmChartTemplate{
|
||||
Spec: v2.HelmChartTemplateSpec{
|
||||
Chart: "chart",
|
||||
SourceRef: v2.CrossNamespaceObjectReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
hc: &sourcev1.HelmChart{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default-test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: sourcev1.HelmChartSpec{
|
||||
Chart: "chart",
|
||||
SourceRef: sourcev1.LocalHelmChartSourceReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectHelmChartStatus: "default/default-test-release",
|
||||
},
|
||||
{
|
||||
name: "modified HelmChart",
|
||||
hr: &v2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v2.HelmReleaseSpec{
|
||||
Interval: metav1.Duration{Duration: time.Minute},
|
||||
Chart: v2.HelmChartTemplate{
|
||||
Spec: v2.HelmChartTemplateSpec{
|
||||
Chart: "chart",
|
||||
SourceRef: v2.CrossNamespaceObjectReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
Namespace: "cross",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: v2.HelmReleaseStatus{
|
||||
HelmChart: "default/default-test-release",
|
||||
},
|
||||
},
|
||||
hc: &sourcev1.HelmChart{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default-test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: sourcev1.HelmChartSpec{
|
||||
Chart: "chart",
|
||||
SourceRef: sourcev1.LocalHelmChartSourceReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectHelmChartStatus: "cross/default-test-release",
|
||||
expectGC: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
g.Expect(v2.AddToScheme(scheme.Scheme)).To(Succeed())
|
||||
g.Expect(sourcev1.AddToScheme(scheme.Scheme)).To(Succeed())
|
||||
|
||||
var c client.Client
|
||||
if tt.hc != nil {
|
||||
c = fake.NewFakeClientWithScheme(scheme.Scheme, tt.hc)
|
||||
} else {
|
||||
c = fake.NewFakeClientWithScheme(scheme.Scheme)
|
||||
}
|
||||
|
||||
r := &HelmReleaseReconciler{
|
||||
Client: c,
|
||||
}
|
||||
|
||||
hc, err := r.reconcileChart(logr.NewContext(context.TODO(), log.NullLogger{}), tt.hr)
|
||||
if tt.expectErr {
|
||||
g.Expect(err).To(HaveOccurred())
|
||||
g.Expect(hc).To(BeNil())
|
||||
} else {
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
g.Expect(hc).NotTo(BeNil())
|
||||
}
|
||||
|
||||
g.Expect(tt.hr.Status.HelmChart).To(Equal(tt.expectHelmChartStatus))
|
||||
|
||||
if tt.expectGC {
|
||||
objKey := client.ObjectKeyFromObject(tt.hc)
|
||||
err = c.Get(context.TODO(), objKey, tt.hc.DeepCopy())
|
||||
g.Expect(apierrors.IsNotFound(err)).To(BeTrue())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelmReleaseReconciler_deleteHelmChart(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
hc *sourcev1.HelmChart
|
||||
hr *v2.HelmRelease
|
||||
expectHelmChartStatus string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "delete existing HelmChart",
|
||||
hc: &sourcev1.HelmChart{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-chart",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
hr: &v2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-release",
|
||||
},
|
||||
Status: v2.HelmReleaseStatus{
|
||||
HelmChart: "default/test-chart",
|
||||
},
|
||||
},
|
||||
expectHelmChartStatus: "",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "delete already removed HelmChart",
|
||||
hc: nil,
|
||||
hr: &v2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-release",
|
||||
},
|
||||
Status: v2.HelmReleaseStatus{
|
||||
HelmChart: "default/test-chart",
|
||||
},
|
||||
},
|
||||
expectHelmChartStatus: "",
|
||||
expectErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
g.Expect(v2.AddToScheme(scheme.Scheme)).To(Succeed())
|
||||
g.Expect(sourcev1.AddToScheme(scheme.Scheme)).To(Succeed())
|
||||
|
||||
var c client.Client
|
||||
if tt.hc != nil {
|
||||
c = fake.NewFakeClientWithScheme(scheme.Scheme, tt.hc)
|
||||
} else {
|
||||
c = fake.NewFakeClientWithScheme(scheme.Scheme)
|
||||
}
|
||||
|
||||
r := &HelmReleaseReconciler{
|
||||
Client: c,
|
||||
}
|
||||
|
||||
err := r.deleteHelmChart(context.TODO(), tt.hr)
|
||||
if tt.expectErr {
|
||||
g.Expect(err).To(HaveOccurred())
|
||||
} else {
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
g.Expect(tt.hr.Status.HelmChart).To(Equal(tt.expectHelmChartStatus))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_buildHelmChartFromTemplate(t *testing.T) {
|
||||
hrWithChartTemplate := v2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v2.HelmReleaseSpec{
|
||||
Interval: metav1.Duration{Duration: time.Minute},
|
||||
Chart: v2.HelmChartTemplate{
|
||||
Spec: v2.HelmChartTemplateSpec{
|
||||
Chart: "chart",
|
||||
Version: "1.0.0",
|
||||
SourceRef: v2.CrossNamespaceObjectReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
Interval: &metav1.Duration{Duration: 2 * time.Minute},
|
||||
ValuesFiles: []string{"values.yaml"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
modify func(release *v2.HelmRelease)
|
||||
want *sourcev1.HelmChart
|
||||
}{
|
||||
{
|
||||
name: "builds HelmChart from HelmChartTemplate",
|
||||
modify: func(*v2.HelmRelease) {},
|
||||
want: &sourcev1.HelmChart{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default-test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: sourcev1.HelmChartSpec{
|
||||
Chart: "chart",
|
||||
Version: "1.0.0",
|
||||
SourceRef: sourcev1.LocalHelmChartSourceReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||
ValuesFiles: []string{"values.yaml"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "takes SourceRef namespace into account",
|
||||
modify: func(hr *v2.HelmRelease) {
|
||||
hr.Spec.Chart.Spec.SourceRef.Namespace = "cross"
|
||||
},
|
||||
want: &sourcev1.HelmChart{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default-test-release",
|
||||
Namespace: "cross",
|
||||
},
|
||||
Spec: sourcev1.HelmChartSpec{
|
||||
Chart: "chart",
|
||||
Version: "1.0.0",
|
||||
SourceRef: sourcev1.LocalHelmChartSourceReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
Interval: metav1.Duration{Duration: 2 * time.Minute},
|
||||
ValuesFiles: []string{"values.yaml"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "falls back to HelmRelease interval",
|
||||
modify: func(hr *v2.HelmRelease) {
|
||||
hr.Spec.Chart.Spec.Interval = nil
|
||||
},
|
||||
want: &sourcev1.HelmChart{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "default-test-release",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: sourcev1.HelmChartSpec{
|
||||
Chart: "chart",
|
||||
Version: "1.0.0",
|
||||
SourceRef: sourcev1.LocalHelmChartSourceReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
Interval: metav1.Duration{Duration: time.Minute},
|
||||
ValuesFiles: []string{"values.yaml"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
hr := hrWithChartTemplate.DeepCopy()
|
||||
tt.modify(hr)
|
||||
g.Expect(buildHelmChartFromTemplate(hr)).To(Equal(tt.want))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_helmChartRequiresUpdate(t *testing.T) {
|
||||
hrWithChartTemplate := v2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-release",
|
||||
},
|
||||
Spec: v2.HelmReleaseSpec{
|
||||
Interval: metav1.Duration{Duration: time.Minute},
|
||||
Chart: v2.HelmChartTemplate{
|
||||
Spec: v2.HelmChartTemplateSpec{
|
||||
Chart: "chart",
|
||||
Version: "1.0.0",
|
||||
SourceRef: v2.CrossNamespaceObjectReference{
|
||||
Name: "test-repository",
|
||||
Kind: "HelmRepository",
|
||||
},
|
||||
Interval: &metav1.Duration{Duration: 2 * time.Minute},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
modify func(*v2.HelmRelease, *sourcev1.HelmChart)
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "detects no change",
|
||||
modify: func(*v2.HelmRelease, *sourcev1.HelmChart) {},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "detects chart change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.Chart = "new"
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "detects version change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.Version = "2.0.0"
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "detects chart source name change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.SourceRef.Name = "new"
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "detects chart source kind change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.SourceRef.Kind = "GitRepository"
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "detects interval change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.Interval = nil
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "detects reconcile strategy change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.ReconcileStrategy = "Revision"
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "detects values files change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.ValuesFiles = []string{"values-prod.yaml"}
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "detects values file change",
|
||||
modify: func(hr *v2.HelmRelease, hc *sourcev1.HelmChart) {
|
||||
hr.Spec.Chart.Spec.ValuesFile = "values-prod.yaml"
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
hr := hrWithChartTemplate.DeepCopy()
|
||||
hc := buildHelmChartFromTemplate(hr)
|
||||
g.Expect(helmChartRequiresUpdate(hr, hc)).To(Equal(false))
|
||||
|
||||
tt.modify(hr, hc)
|
||||
g.Expect(helmChartRequiresUpdate(hr, hc)).To(Equal(tt.want))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
Copyright 2020 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 controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
v2 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||
)
|
||||
|
||||
func TestHelmReleaseReconciler_composeValues(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
_ = corev1.AddToScheme(scheme)
|
||||
_ = v2.AddToScheme(scheme)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
resources []runtime.Object
|
||||
references []v2.ValuesReference
|
||||
values string
|
||||
want chartutil.Values
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "merges",
|
||||
resources: []runtime.Object{
|
||||
valuesConfigMap("values", map[string]string{
|
||||
"values.yaml": `flat: value
|
||||
nested:
|
||||
configuration: value
|
||||
`,
|
||||
}),
|
||||
valuesSecret("values", map[string][]byte{
|
||||
"values.yaml": []byte(`flat:
|
||||
nested: value
|
||||
nested: value
|
||||
`),
|
||||
}),
|
||||
},
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "ConfigMap",
|
||||
Name: "values",
|
||||
},
|
||||
{
|
||||
Kind: "Secret",
|
||||
Name: "values",
|
||||
},
|
||||
},
|
||||
values: `
|
||||
other: values
|
||||
`,
|
||||
want: chartutil.Values{
|
||||
"flat": map[string]interface{}{
|
||||
"nested": "value",
|
||||
},
|
||||
"nested": "value",
|
||||
"other": "values",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "target path",
|
||||
resources: []runtime.Object{
|
||||
valuesSecret("values", map[string][]byte{"single": []byte("value")}),
|
||||
},
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "Secret",
|
||||
Name: "values",
|
||||
ValuesKey: "single",
|
||||
TargetPath: "merge.at.specific.path",
|
||||
},
|
||||
},
|
||||
want: chartutil.Values{
|
||||
"merge": map[string]interface{}{
|
||||
"at": map[string]interface{}{
|
||||
"specific": map[string]interface{}{
|
||||
"path": "value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "target path with boolean value",
|
||||
resources: []runtime.Object{
|
||||
valuesSecret("values", map[string][]byte{"single": []byte("true")}),
|
||||
},
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "Secret",
|
||||
Name: "values",
|
||||
ValuesKey: "single",
|
||||
TargetPath: "merge.at.specific.path",
|
||||
},
|
||||
},
|
||||
want: chartutil.Values{
|
||||
"merge": map[string]interface{}{
|
||||
"at": map[string]interface{}{
|
||||
"specific": map[string]interface{}{
|
||||
"path": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "target path with set-string behavior",
|
||||
resources: []runtime.Object{
|
||||
valuesSecret("values", map[string][]byte{"single": []byte("\"true\"")}),
|
||||
},
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "Secret",
|
||||
Name: "values",
|
||||
ValuesKey: "single",
|
||||
TargetPath: "merge.at.specific.path",
|
||||
},
|
||||
},
|
||||
want: chartutil.Values{
|
||||
"merge": map[string]interface{}{
|
||||
"at": map[string]interface{}{
|
||||
"specific": map[string]interface{}{
|
||||
"path": "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "values reference to non existing secret",
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "Secret",
|
||||
Name: "missing",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "optional values reference to non existing secret",
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "Secret",
|
||||
Name: "missing",
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
want: chartutil.Values{},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "values reference to non existing config map",
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "ConfigMap",
|
||||
Name: "missing",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "optional values reference to non existing config map",
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "ConfigMap",
|
||||
Name: "missing",
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
want: chartutil.Values{},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "missing secret key",
|
||||
resources: []runtime.Object{
|
||||
valuesSecret("values", nil),
|
||||
},
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "Secret",
|
||||
Name: "values",
|
||||
ValuesKey: "nonexisting",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "missing config map key",
|
||||
resources: []runtime.Object{
|
||||
valuesConfigMap("values", nil),
|
||||
},
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "ConfigMap",
|
||||
Name: "values",
|
||||
ValuesKey: "nonexisting",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "unsupported values reference kind",
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "Unsupported",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid values",
|
||||
resources: []runtime.Object{
|
||||
valuesConfigMap("values", map[string]string{
|
||||
"values.yaml": `
|
||||
invalid`,
|
||||
}),
|
||||
},
|
||||
references: []v2.ValuesReference{
|
||||
{
|
||||
Kind: "ConfigMap",
|
||||
Name: "values",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := fake.NewFakeClientWithScheme(scheme, tt.resources...)
|
||||
r := &HelmReleaseReconciler{Client: c}
|
||||
var values *apiextensionsv1.JSON
|
||||
if tt.values != "" {
|
||||
v, _ := yaml.YAMLToJSON([]byte(tt.values))
|
||||
values = &apiextensionsv1.JSON{Raw: v}
|
||||
}
|
||||
hr := v2.HelmRelease{
|
||||
Spec: v2.HelmReleaseSpec{
|
||||
ValuesFrom: tt.references,
|
||||
Values: values,
|
||||
},
|
||||
}
|
||||
got, err := r.composeValues(logr.NewContext(context.TODO(), log.NullLogger{}), hr)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("composeValues() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("composeValues() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func valuesSecret(name string, data map[string][]byte) *corev1.Secret {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func valuesConfigMap(name string, data map[string]string) *corev1.ConfigMap {
|
||||
return &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||
Data: data,
|
||||
}
|
||||
}
|
|
@ -14,18 +14,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package predicates
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/fluxcd/pkg/runtime/conditions"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
)
|
||||
|
||||
// SourceRevisionChangePredicate detects revision changes to the v1.Artifact of
|
||||
// a v1.Source object.
|
||||
type SourceRevisionChangePredicate struct {
|
||||
predicate.Funcs
|
||||
}
|
||||
|
@ -50,21 +47,7 @@ func (SourceRevisionChangePredicate) Update(e event.UpdateEvent) bool {
|
|||
}
|
||||
|
||||
if oldSource.GetArtifact() != nil && newSource.GetArtifact() != nil &&
|
||||
!oldSource.GetArtifact().HasRevision(newSource.GetArtifact().Revision) {
|
||||
return true
|
||||
}
|
||||
|
||||
oldConditions, ok := e.ObjectOld.(conditions.Getter)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
newConditions, ok := e.ObjectNew.(conditions.Getter)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if !conditions.IsReady(oldConditions) && conditions.IsReady(newConditions) {
|
||||
oldSource.GetArtifact().Revision != newSource.GetArtifact().Revision {
|
||||
return true
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2020 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 controllers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
||||
"github.com/fluxcd/helm-controller/api/v2beta1"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
|
||||
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
|
||||
|
||||
var cfg *rest.Config
|
||||
var k8sClient client.Client
|
||||
var testEnv *envtest.Environment
|
||||
|
||||
func TestAPIs(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
|
||||
RunSpecsWithDefaultAndCustomReporters(t,
|
||||
"Controller Suite",
|
||||
[]Reporter{printer.NewlineReporter{}})
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func(done Done) {
|
||||
logf.SetLogger(
|
||||
zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)),
|
||||
)
|
||||
|
||||
By("bootstrapping test environment")
|
||||
testEnv = &envtest.Environment{
|
||||
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
|
||||
}
|
||||
|
||||
var err error
|
||||
cfg, err = testEnv.Start()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(cfg).ToNot(BeNil())
|
||||
|
||||
err = v2beta1.AddToScheme(scheme.Scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// +kubebuilder:scaffold:scheme
|
||||
|
||||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(k8sClient).ToNot(BeNil())
|
||||
|
||||
close(done)
|
||||
}, 60)
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
By("tearing down the test environment")
|
||||
err := testEnv.Stop()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue