Compare commits

..

No commits in common. 'main' and 'v2.3.0' have entirely different histories.
main ... v2.3.0

@ -44,12 +44,15 @@
description: Feature request proposals in the RFC format description: Feature request proposals in the RFC format
color: '#D621C3' color: '#D621C3'
aliases: ['area/RFC'] aliases: ['area/RFC']
- name: backport:release/v2.3.x - name: backport:release/v2.0.x
description: To be backported to release/v2.3.x description: To be backported to release/v2.0.x
color: '#ffd700'
- name: backport:release/v2.1.x
description: To be backported to release/v2.1.x
color: '#ffd700' color: '#ffd700'
- name: backport:release/v2.4.x - name: backport:release/v2.2.x
description: To be backported to release/v2.4.x description: To be backported to release/v2.2.x
color: '#ffd700' color: '#ffd700'
- name: backport:release/v2.5.x - name: backport:release/v2.3.x
description: To be backported to release/v2.5.x description: To be backported to release/v2.3.x
color: '#ffd700' color: '#ffd700'

@ -24,6 +24,6 @@ jobs:
name: action on ${{ matrix.version }} name: action on ${{ matrix.version }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup flux - name: Setup flux
uses: ./action uses: ./action

@ -4,9 +4,6 @@ on:
pull_request_target: pull_request_target:
types: [closed, labeled] types: [closed, labeled]
permissions:
contents: read
jobs: jobs:
pull-request: pull-request:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -16,11 +13,11 @@ jobs:
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name)) if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with: with:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs - name: Create backport PRs
uses: korthout/backport-action@be567af183754f6a5d831ae90f648954763f17f5 # v3.1.0 uses: korthout/backport-action@ef20d86abccbac3ee3a73cb2efbdc06344c390e5 # v2.5.0
# xref: https://github.com/korthout/backport-action#inputs # xref: https://github.com/korthout/backport-action#inputs
with: with:
# Use token to allow workflows to be triggered for the created PR # Use token to allow workflows to be triggered for the created PR

@ -9,23 +9,24 @@ permissions:
contents: read contents: read
env: env:
GO_VERSION: 1.23.x GO_VERSION: 1.22.x
jobs: jobs:
conform-kubernetes: conform-kubernetes:
runs-on: # Hosted on Equinix
group: "ARM64" # Docs: https://github.com/fluxcd/flux2/tree/main/.github/runners
runs-on: [self-hosted, Linux, ARM64, equinix]
strategy: strategy:
matrix: matrix:
# Keep this list up-to-date with https://endoflife.date/kubernetes # Keep this list up-to-date with https://endoflife.date/kubernetes
# Build images with https://github.com/fluxcd/flux-benchmark/actions/workflows/build-kind.yaml # Build images with https://github.com/fluxcd/flux-benchmark/actions/workflows/build-kind.yaml
KUBERNETES_VERSION: [1.30.9, 1.31.5, 1.32.1 ] KUBERNETES_VERSION: [ 1.28.9, 1.29.4, 1.30.0 ]
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: ${{ env.GO_VERSION }} go-version: ${{ env.GO_VERSION }}
cache-dependency-path: | cache-dependency-path: |
@ -39,15 +40,18 @@ jobs:
- name: Build - name: Build
run: | run: |
make build make build
- name: Setup Kubernetes - name: Setup Kubernetes Kind
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 run: |
with: kind create cluster \
version: v0.22.0 --wait 5m \
cluster_name: ${{ steps.prep.outputs.CLUSTER }} --name ${{ steps.prep.outputs.CLUSTER }} \
node_image: ghcr.io/fluxcd/kindest/node:v${{ matrix.KUBERNETES_VERSION }}-arm64 --kubeconfig=/tmp/${{ steps.prep.outputs.CLUSTER }} \
--image=ghcr.io/fluxcd/kindest/node:v${{ matrix.KUBERNETES_VERSION }}-arm64
- name: Run e2e tests - name: Run e2e tests
run: TEST_KUBECONFIG=$HOME/.kube/config make e2e run: TEST_KUBECONFIG=/tmp/${{ steps.prep.outputs.CLUSTER }} make e2e
- name: Run multi-tenancy tests - name: Run multi-tenancy tests
env:
KUBECONFIG: /tmp/${{ steps.prep.outputs.CLUSTER }}
run: | run: |
./bin/flux install ./bin/flux install
./bin/flux create source git flux-system \ ./bin/flux create source git flux-system \
@ -64,11 +68,18 @@ jobs:
kubectl -n apps wait helmrelease/podinfo --for=condition=ready --timeout=1m kubectl -n apps wait helmrelease/podinfo --for=condition=ready --timeout=1m
- name: Debug failure - name: Debug failure
if: failure() if: failure()
env:
KUBECONFIG: /tmp/${{ steps.prep.outputs.CLUSTER }}
run: | run: |
kubectl -n flux-system get all kubectl -n flux-system get all
kubectl -n flux-system describe po kubectl -n flux-system describe po
kubectl -n flux-system logs deploy/source-controller kubectl -n flux-system logs deploy/source-controller
kubectl -n flux-system logs deploy/kustomize-controller kubectl -n flux-system logs deploy/kustomize-controller
- name: Cleanup
if: always()
run: |
kind delete cluster --name ${{ steps.prep.outputs.CLUSTER }}
rm /tmp/${{ steps.prep.outputs.CLUSTER }}
conform-k3s: conform-k3s:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -76,13 +87,13 @@ jobs:
matrix: matrix:
# Keep this list up-to-date with https://endoflife.date/kubernetes # Keep this list up-to-date with https://endoflife.date/kubernetes
# Available versions can be found with "replicated cluster versions" # Available versions can be found with "replicated cluster versions"
K3S_VERSION: [ 1.30.9, 1.31.5, 1.32.1 ] K3S_VERSION: [ 1.28.7, 1.29.2 ]
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: ${{ env.GO_VERSION }} go-version: ${{ env.GO_VERSION }}
cache-dependency-path: | cache-dependency-path: |
@ -97,7 +108,7 @@ jobs:
KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml" KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml"
echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/kustomize@main
- name: Build - name: Build
run: make build-dev run: make build-dev
- name: Create repository - name: Create repository
@ -107,7 +118,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: Create cluster - name: Create cluster
id: create-cluster id: create-cluster
uses: replicatedhq/replicated-actions/create-cluster@c98ab3b97925af5db9faf3f9676df7a9c6736985 # v1.17.0 uses: replicatedhq/compatibility-actions/create-cluster@v1
with: with:
api-token: ${{ secrets.REPLICATED_API_TOKEN }} api-token: ${{ secrets.REPLICATED_API_TOKEN }}
kubernetes-distribution: "k3s" kubernetes-distribution: "k3s"
@ -151,7 +162,7 @@ jobs:
kubectl delete ns flux-system --wait kubectl delete ns flux-system --wait
- name: Delete cluster - name: Delete cluster
if: ${{ always() }} if: ${{ always() }}
uses: replicatedhq/replicated-actions/remove-cluster@c98ab3b97925af5db9faf3f9676df7a9c6736985 # v1.17.0 uses: replicatedhq/replicated-actions/remove-cluster@v1
continue-on-error: true continue-on-error: true
with: with:
api-token: ${{ secrets.REPLICATED_API_TOKEN }} api-token: ${{ secrets.REPLICATED_API_TOKEN }}
@ -169,13 +180,13 @@ jobs:
strategy: strategy:
matrix: matrix:
# Keep this list up-to-date with https://endoflife.date/red-hat-openshift # Keep this list up-to-date with https://endoflife.date/red-hat-openshift
OPENSHIFT_VERSION: [ 4.17.0-okd ] OPENSHIFT_VERSION: [ 4.15.0-okd ]
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: ${{ env.GO_VERSION }} go-version: ${{ env.GO_VERSION }}
cache-dependency-path: | cache-dependency-path: |
@ -190,7 +201,7 @@ jobs:
KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml" KUBECONFIG_PATH="$(git rev-parse --show-toplevel)/bin/kubeconfig.yaml"
echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT echo "kubeconfig-path=${KUBECONFIG_PATH}" >> $GITHUB_OUTPUT
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/kustomize@main
- name: Build - name: Build
run: make build-dev run: make build-dev
- name: Create repository - name: Create repository
@ -200,7 +211,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: Create cluster - name: Create cluster
id: create-cluster id: create-cluster
uses: replicatedhq/replicated-actions/create-cluster@c98ab3b97925af5db9faf3f9676df7a9c6736985 # v1.17.0 uses: replicatedhq/compatibility-actions/create-cluster@v1
with: with:
api-token: ${{ secrets.REPLICATED_API_TOKEN }} api-token: ${{ secrets.REPLICATED_API_TOKEN }}
kubernetes-distribution: "openshift" kubernetes-distribution: "openshift"
@ -242,7 +253,7 @@ jobs:
kubectl delete ns flux-system --wait kubectl delete ns flux-system --wait
- name: Delete cluster - name: Delete cluster
if: ${{ always() }} if: ${{ always() }}
uses: replicatedhq/replicated-actions/remove-cluster@c98ab3b97925af5db9faf3f9676df7a9c6736985 # v1.17.0 uses: replicatedhq/replicated-actions/remove-cluster@v1
continue-on-error: true continue-on-error: true
with: with:
api-token: ${{ secrets.REPLICATED_API_TOKEN }} api-token: ${{ secrets.REPLICATED_API_TOKEN }}

@ -30,14 +30,12 @@ jobs:
if: false && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]' if: false && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
steps: steps:
- name: CheckoutD - name: CheckoutD
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: 1.23.x go-version: 1.22.x
cache-dependency-path: tests/integration/go.sum cache-dependency-path: tests/integration/go.sum
- name: Setup Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
- name: Setup Flux CLI - name: Setup Flux CLI
run: make build run: make build
working-directory: ./ working-directory: ./
@ -49,7 +47,7 @@ jobs:
env: env:
SOPS_VER: 3.7.1 SOPS_VER: 3.7.1
- name: Authenticate to Azure - name: Authenticate to Azure
uses: Azure/login@a65d910e8af852a8061c627c456678983e180302 # v1.4.6 uses: Azure/login@6b2456866fc08b011acb422a92a4aa20e2c4de32 # v1.4.6
with: with:
creds: '{"clientId":"${{ secrets.AZ_ARM_CLIENT_ID }}","clientSecret":"${{ secrets.AZ_ARM_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZ_ARM_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZ_ARM_TENANT_ID }}"}' creds: '{"clientId":"${{ secrets.AZ_ARM_CLIENT_ID }}","clientSecret":"${{ secrets.AZ_ARM_CLIENT_SECRET }}","subscriptionId":"${{ secrets.AZ_ARM_SUBSCRIPTION_ID }}","tenantId":"${{ secrets.AZ_ARM_TENANT_ID }}"}'
- name: Set dynamic variables in .env - name: Set dynamic variables in .env

@ -17,27 +17,27 @@ jobs:
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]' if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: 1.23.x go-version: 1.22.x
cache-dependency-path: | cache-dependency-path: |
**/go.sum **/go.sum
**/go.mod **/go.mod
- name: Setup Kubernetes - name: Setup Kubernetes
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0
with: with:
version: v0.24.0 version: v0.22.0
cluster_name: kind cluster_name: kind
# The versions below should target the newest Kubernetes version # The versions below should target the newest Kubernetes version
# Keep this up-to-date with https://endoflife.date/kubernetes # Keep this up-to-date with https://endoflife.date/kubernetes
node_image: ghcr.io/fluxcd/kindest/node:v1.31.0-amd64 node_image: ghcr.io/fluxcd/kindest/node:v1.30.0-amd64
kubectl_version: v1.31.0 kubectl_version: v1.30.0
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/kustomize@main
- name: Setup yq - name: Setup yq
uses: fluxcd/pkg/actions/yq@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/yq@main
- name: Build - name: Build
run: make build-dev run: make build-dev
- name: Set outputs - name: Set outputs

@ -29,14 +29,12 @@ jobs:
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]' if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: 1.23.x go-version: 1.22.x
cache-dependency-path: tests/integration/go.sum cache-dependency-path: tests/integration/go.sum
- name: Setup Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
- name: Setup Flux CLI - name: Setup Flux CLI
run: make build run: make build
working-directory: ./ working-directory: ./
@ -48,19 +46,19 @@ jobs:
env: env:
SOPS_VER: 3.7.1 SOPS_VER: 3.7.1
- name: Authenticate to Google Cloud - name: Authenticate to Google Cloud
uses: google-github-actions/auth@71f986410dfbc7added4569d411d040a91dc6935 # v2.1.8 uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c # v2.1.2
id: 'auth' id: 'auth'
with: with:
credentials_json: '${{ secrets.FLUX2_E2E_GOOGLE_CREDENTIALS }}' credentials_json: '${{ secrets.FLUX2_E2E_GOOGLE_CREDENTIALS }}'
token_format: 'access_token' token_format: 'access_token'
- name: Setup gcloud - name: Setup gcloud
uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a # v2.1.4 uses: google-github-actions/setup-gcloud@98ddc00a17442e89a24bbf282954a3b65ce6d200 # v2.1.0
- name: Setup QEMU - name: Setup QEMU
uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # v3.4.0 uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
- name: Setup Docker Buildx - name: Setup Docker Buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0 uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
- name: Log into us-central1-docker.pkg.dev - name: Log into us-central1-docker.pkg.dev
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with: with:
registry: us-central1-docker.pkg.dev registry: us-central1-docker.pkg.dev
username: oauth2accesstoken username: oauth2accesstoken

@ -23,30 +23,30 @@ jobs:
- 5000:5000 - 5000:5000
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: 1.23.x go-version: 1.22.x
cache-dependency-path: | cache-dependency-path: |
**/go.sum **/go.sum
**/go.mod **/go.mod
- name: Setup Kubernetes - name: Setup Kubernetes
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 uses: helm/kind-action@0025e74a8c7512023d06dc019c617aa3cf561fde # v1.10.0
with: with:
version: v0.24.0 version: v0.22.0
cluster_name: kind cluster_name: kind
wait: 5s wait: 5s
config: .github/kind/config.yaml # disable KIND-net config: .github/kind/config.yaml # disable KIND-net
# The versions below should target the oldest supported Kubernetes version # The versions below should target the oldest supported Kubernetes version
# Keep this up-to-date with https://endoflife.date/kubernetes # Keep this up-to-date with https://endoflife.date/kubernetes
node_image: ghcr.io/fluxcd/kindest/node:v1.30.9-amd64 node_image: ghcr.io/fluxcd/kindest/node:v1.28.9-amd64
kubectl_version: v1.30.9 kubectl_version: v1.28.9
- name: Setup Calico for network policy - name: Setup Calico for network policy
run: | run: |
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/calico.yaml
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/kustomize@main
- name: Run tests - name: Run tests
run: make test run: make test
- name: Run e2e tests - name: Run e2e tests

@ -19,21 +19,21 @@ jobs:
actions: read actions: read
contents: read contents: read
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Run analysis - name: Run analysis
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: sarif
repo_token: ${{ secrets.GITHUB_TOKEN }} repo_token: ${{ secrets.GITHUB_TOKEN }}
publish_results: true publish_results: true
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with: with:
name: SARIF file name: SARIF file
path: results.sarif path: results.sarif
retention-days: 5 retention-days: 5
- name: Upload SARIF results - name: Upload SARIF results
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
with: with:
sarif_file: results.sarif sarif_file: results.sarif

@ -2,7 +2,7 @@ name: release
on: on:
push: push:
tags: ["v*"] tags: [ 'v*' ]
permissions: permissions:
contents: read contents: read
@ -20,33 +20,33 @@ jobs:
packages: write # needed for ghcr access packages: write # needed for ghcr access
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Unshallow - name: Unshallow
run: git fetch --prune --unshallow run: git fetch --prune --unshallow
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: 1.23.x go-version: 1.22.x
cache: false cache: false
- name: Setup QEMU - name: Setup QEMU
uses: docker/setup-qemu-action@4574d27a4764455b42196d70a065bc6853246a25 # v3.4.0 uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
- name: Setup Docker Buildx - name: Setup Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0 uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
- name: Setup Syft - name: Setup Syft
uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0 uses: anchore/sbom-action/download-syft@7ccf588e3cf3cc2611714c2eeae48550fbc17552 # v0.15.11
- name: Setup Cosign - name: Setup Cosign
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0 uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/kustomize@main
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with: with:
registry: ghcr.io registry: ghcr.io
username: fluxcdbot username: fluxcdbot
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GHCR_TOKEN }}
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with: with:
username: fluxcdbot username: fluxcdbot
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }} password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
@ -59,19 +59,30 @@ jobs:
run: | run: |
kustomize build manifests/crds > all-crds.yaml kustomize build manifests/crds > all-crds.yaml
- name: Generate OpenAPI JSON schemas from CRDs - name: Generate OpenAPI JSON schemas from CRDs
uses: fluxcd/pkg/actions/crdjsonschema@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/crdjsonschema@main
with: with:
crd: all-crds.yaml crd: all-crds.yaml
output: schemas output: schemas
- name: Archive the OpenAPI JSON schemas - name: Archive the OpenAPI JSON schemas
run: | run: |
tar -czvf ./output/crd-schemas.tar.gz -C schemas . tar -czvf ./output/crd-schemas.tar.gz -C schemas .
- name: Download release notes utility
env:
GH_REL_URL: https://github.com/buchanae/github-release-notes/releases/download/0.2.0/github-release-notes-linux-amd64-0.2.0.tar.gz
run: cd /tmp && curl -sSL ${GH_REL_URL} | tar xz && sudo mv github-release-notes /usr/local/bin/
- name: Generate release notes
run: |
NOTES="./output/notes.md"
echo '## CLI Changelog' > ${NOTES}
github-release-notes -org fluxcd -repo flux2 -since-latest-release -include-author >> ${NOTES}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run GoReleaser - name: Run GoReleaser
id: run-goreleaser id: run-goreleaser
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0 uses: goreleaser/goreleaser-action@5742e2a039330cbb23ebf35f046f814d4c6ff811 # v5.1.0
with: with:
version: latest version: latest
args: release --skip=validate args: release --release-notes=output/notes.md --skip-validate
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
@ -99,9 +110,9 @@ jobs:
id-token: write id-token: write
packages: write packages: write
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/kustomize@main
- name: Setup Flux CLI - name: Setup Flux CLI
uses: ./action/ uses: ./action/
- name: Prepare - name: Prepare
@ -110,13 +121,13 @@ jobs:
VERSION=$(flux version --client | awk '{ print $NF }') VERSION=$(flux version --client | awk '{ print $NF }')
echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Login to GHCR - name: Login to GHCR
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with: with:
registry: ghcr.io registry: ghcr.io
username: fluxcdbot username: fluxcdbot
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GHCR_TOKEN }}
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
with: with:
username: fluxcdbot username: fluxcdbot
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }} password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
@ -144,7 +155,7 @@ jobs:
--path="./flux-system" \ --path="./flux-system" \
--source=${{ github.repositoryUrl }} \ --source=${{ github.repositoryUrl }} \
--revision="${{ github.ref_name }}@sha1:${{ github.sha }}" --revision="${{ github.ref_name }}@sha1:${{ github.sha }}"
- uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0 - uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
- name: Sign manifests - name: Sign manifests
env: env:
COSIGN_EXPERIMENTAL: 1 COSIGN_EXPERIMENTAL: 1
@ -197,4 +208,4 @@ jobs:
digest: ${{ needs.release-flux-cli.outputs.image_digest }} digest: ${{ needs.release-flux-cli.outputs.image_digest }}
registry-username: fluxcdbot registry-username: fluxcdbot
secrets: secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }} registry-password: ${{ secrets.GHCR_TOKEN }}

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]' if: github.actor != 'dependabot[bot]'
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Run FOSSA scan and upload build data - name: Run FOSSA scan and upload build data
uses: fossa-contrib/fossa-action@cdc5065bcdee31a32e47d4585df72d66e8e941c2 # v3.0.0 uses: fossa-contrib/fossa-action@cdc5065bcdee31a32e47d4585df72d66e8e941c2 # v3.0.0
with: with:
@ -31,11 +31,11 @@ jobs:
security-events: write security-events: write
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]' if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && github.actor != 'dependabot[bot]'
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Kustomize - name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@c964ce7b91949ff4b5e3959db4f1d7bb2e029a49 # main uses: fluxcd/pkg/actions/kustomize@main
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version-file: 'go.mod' go-version-file: 'go.mod'
cache-dependency-path: | cache-dependency-path: |
@ -54,7 +54,7 @@ jobs:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: Upload result to GitHub Code Scanning - name: Upload result to GitHub Code Scanning
continue-on-error: true continue-on-error: true
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 uses: github/codeql-action/upload-sarif@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
with: with:
sarif_file: snyk.sarif sarif_file: snyk.sarif
@ -65,22 +65,22 @@ jobs:
if: github.actor != 'dependabot[bot]' if: github.actor != 'dependabot[bot]'
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version-file: 'go.mod' go-version-file: 'go.mod'
cache-dependency-path: | cache-dependency-path: |
**/go.sum **/go.sum
**/go.mod **/go.mod
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 uses: github/codeql-action/init@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
with: with:
languages: go languages: go
# xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# xref: https://codeql.github.com/codeql-query-help/go/ # xref: https://codeql.github.com/codeql-query-help/go/
queries: security-and-quality queries: security-and-quality
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 uses: github/codeql-action/autobuild@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9 uses: github/codeql-action/analyze@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4

@ -17,7 +17,7 @@ jobs:
permissions: permissions:
issues: write issues: write
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3 - uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
with: with:
# Configuration file # Configuration file

@ -18,11 +18,11 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Check out code - name: Check out code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Setup Go - name: Setup Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
with: with:
go-version: 1.23.x go-version: 1.22.x
cache-dependency-path: | cache-dependency-path: |
**/go.sum **/go.sum
**/go.mod **/go.mod
@ -84,7 +84,7 @@ jobs:
- name: Create Pull Request - name: Create Pull Request
id: cpr id: cpr
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6 uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
with: with:
token: ${{ secrets.BOT_GITHUB_TOKEN }} token: ${{ secrets.BOT_GITHUB_TOKEN }}
commit-message: | commit-message: |

@ -1,6 +1,4 @@
project_name: flux project_name: flux
changelog:
use: github-native
builds: builds:
- <<: &build_defaults - <<: &build_defaults
binary: flux binary: flux
@ -17,7 +15,7 @@ builds:
- arm64 - arm64
- arm - arm
goarm: goarm:
- "7" - 7
- <<: *build_defaults - <<: *build_defaults
id: darwin id: darwin
goos: goos:
@ -75,11 +73,11 @@ signs:
output: true output: true
brews: brews:
- name: flux - name: flux
repository: tap:
owner: fluxcd owner: fluxcd
name: homebrew-tap name: homebrew-tap
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
directory: Formula folder: Formula
homepage: "https://fluxcd.io/" homepage: "https://fluxcd.io/"
description: "Flux CLI" description: "Flux CLI"
install: | install: |

@ -1,5 +0,0 @@
annotations:
- checks:
- dangerous-workflow
reasons:
- reason: not-applicable # This workflow does not run untrusted code, the bot will only backport a code if the a PR was approved and merged into main.

@ -1,16 +1,15 @@
FROM alpine:3.21 AS builder FROM alpine:3.19 as builder
RUN apk add --no-cache ca-certificates curl RUN apk add --no-cache ca-certificates curl
ARG ARCH=linux/amd64 ARG ARCH=linux/amd64
ARG KUBECTL_VER=1.32.2 ARG KUBECTL_VER=1.30.0
RUN curl -sL https://dl.k8s.io/release/v${KUBECTL_VER}/bin/${ARCH}/kubectl \ RUN curl -sL https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/${ARCH}/kubectl \
-o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl -o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl && \
kubectl version --client=true
RUN kubectl version --client=true FROM alpine:3.19 as flux-cli
FROM alpine:3.21 AS flux-cli
RUN apk add --no-cache ca-certificates RUN apk add --no-cache ca-certificates

@ -17,8 +17,8 @@ rwildcard=$(foreach d,$(wildcard $(addsuffix *,$(1))),$(call rwildcard,$(d)/,$(2
all: test build all: test build
tidy: tidy:
go mod tidy -compat=1.23 go mod tidy -compat=1.22
cd tests/integration && go mod tidy -compat=1.23 cd tests/integration && go mod tidy -compat=1.22
fmt: fmt:
go fmt ./... go fmt ./...

@ -2,7 +2,7 @@
[![release](https://img.shields.io/github/release/fluxcd/flux2/all.svg)](https://github.com/fluxcd/flux2/releases) [![release](https://img.shields.io/github/release/fluxcd/flux2/all.svg)](https://github.com/fluxcd/flux2/releases)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4782/badge)](https://bestpractices.coreinfrastructure.org/projects/4782) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4782/badge)](https://bestpractices.coreinfrastructure.org/projects/4782)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/fluxcd/flux2/badge)](https://scorecard.dev/viewer/?uri=github.com/fluxcd/flux2) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/fluxcd/flux2/badge)](https://api.securityscorecards.dev/projects/github.com/fluxcd/flux2)
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Ffluxcd%2Fflux2.svg?type=shield)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Ffluxcd%2Fflux2?ref=badge_shield) [![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Ffluxcd%2Fflux2.svg?type=shield)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Ffluxcd%2Fflux2?ref=badge_shield)
[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/flux2)](https://artifacthub.io/packages/helm/fluxcd-community/flux2) [![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/flux2)](https://artifacthub.io/packages/helm/fluxcd-community/flux2)
[![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://fluxcd.io/flux/security/slsa-assessment) [![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://fluxcd.io/flux/security/slsa-assessment)

@ -226,7 +226,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
secretOpts.Username = bServerArgs.username secretOpts.Username = bServerArgs.username
} }
secretOpts.Password = bitbucketToken secretOpts.Password = bitbucketToken
secretOpts.CACrt = caBundle secretOpts.CAFile = caBundle
} else { } else {
keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password) keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password)
if err != nil { if err != nil {

@ -243,7 +243,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
secretOpts.Password = gitArgs.password secretOpts.Password = gitArgs.password
} }
secretOpts.CACrt = caBundle secretOpts.CAFile = caBundle
// Remove port of the given host when not syncing over HTTP/S to not assume port for protocol // Remove port of the given host when not syncing over HTTP/S to not assume port for protocol
// This _might_ be overwritten later on by e.g. --ssh-hostname // This _might_ be overwritten later on by e.g. --ssh-hostname

@ -210,7 +210,7 @@ func bootstrapGiteaCmdRun(cmd *cobra.Command, args []string) error {
if bootstrapArgs.tokenAuth { if bootstrapArgs.tokenAuth {
secretOpts.Username = "git" secretOpts.Username = "git"
secretOpts.Password = gtToken secretOpts.Password = gtToken
secretOpts.CACrt = caBundle secretOpts.CAFile = caBundle
} else { } else {
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm) secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits) secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)

@ -217,7 +217,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
if bootstrapArgs.tokenAuth { if bootstrapArgs.tokenAuth {
secretOpts.Username = "git" secretOpts.Username = "git"
secretOpts.Password = ghToken secretOpts.Password = ghToken
secretOpts.CACrt = caBundle secretOpts.CAFile = caBundle
} else { } else {
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm) secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits) secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)

@ -24,7 +24,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/fluxcd/go-git-providers/gitprovider"
"github.com/fluxcd/pkg/git" "github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/gogit" "github.com/fluxcd/pkg/git/gogit"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -59,14 +58,14 @@ the bootstrap command will perform an upgrade if needed.`,
# Run bootstrap for a repository path # Run bootstrap for a repository path
flux bootstrap gitlab --owner=<group> --repository=<repository name> --path=dev-cluster flux bootstrap gitlab --owner=<group> --repository=<repository name> --path=dev-cluster
# Run bootstrap for a public repository # Run bootstrap for a public repository on a personal account
flux bootstrap gitlab --owner=<group> --repository=<repository name> --visibility=public --token-auth flux bootstrap gitlab --owner=<user> --repository=<repository name> --private=false --personal --token-auth
# Run bootstrap for a private repository hosted on a GitLab server # Run bootstrap for a private repository hosted on a GitLab server
flux bootstrap gitlab --owner=<group> --repository=<repository name> --hostname=<gitlab_url> --token-auth flux bootstrap gitlab --owner=<group> --repository=<repository name> --hostname=<domain> --token-auth
# Run bootstrap for an existing repository with a branch named main # Run bootstrap for an existing repository with a branch named main
flux bootstrap gitlab --owner=<group> --repository=<repository name> --branch=main --token-auth flux bootstrap gitlab --owner=<organization> --repository=<repository name> --branch=main --token-auth
# Run bootstrap for a private repository using Deploy Token authentication # Run bootstrap for a private repository using Deploy Token authentication
flux bootstrap gitlab --owner=<group> --repository=<repository name> --deploy-token-auth flux bootstrap gitlab --owner=<group> --repository=<repository name> --deploy-token-auth
@ -86,7 +85,6 @@ type gitlabFlags struct {
repository string repository string
interval time.Duration interval time.Duration
personal bool personal bool
visibility flags.GitLabVisibility
private bool private bool
hostname string hostname string
path flags.SafeRelativePath path flags.SafeRelativePath
@ -96,13 +94,7 @@ type gitlabFlags struct {
deployTokenAuth bool deployTokenAuth bool
} }
func NewGitlabFlags() gitlabFlags { var gitlabArgs gitlabFlags
return gitlabFlags{
visibility: flags.GitLabVisibility(gitprovider.RepositoryVisibilityPrivate),
}
}
var gitlabArgs = NewGitlabFlags()
func init() { func init() {
bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.owner, "owner", "", "GitLab user or group name") bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.owner, "owner", "", "GitLab user or group name")
@ -110,8 +102,6 @@ func init() {
bootstrapGitLabCmd.Flags().StringSliceVar(&gitlabArgs.teams, "team", []string{}, "GitLab teams to be given maintainer access (also accepts comma-separated values)") bootstrapGitLabCmd.Flags().StringSliceVar(&gitlabArgs.teams, "team", []string{}, "GitLab teams to be given maintainer access (also accepts comma-separated values)")
bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.personal, "personal", false, "if true, the owner is assumed to be a GitLab user; otherwise a group") bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.personal, "personal", false, "if true, the owner is assumed to be a GitLab user; otherwise a group")
bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.private, "private", true, "if true, the repository is setup or configured as private") bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.private, "private", true, "if true, the repository is setup or configured as private")
bootstrapGitLabCmd.Flags().MarkDeprecated("private", "use --visibility instead")
bootstrapGitLabCmd.Flags().Var(&gitlabArgs.visibility, "visibility", gitlabArgs.visibility.Description())
bootstrapGitLabCmd.Flags().DurationVar(&gitlabArgs.interval, "interval", time.Minute, "sync interval") bootstrapGitLabCmd.Flags().DurationVar(&gitlabArgs.interval, "interval", time.Minute, "sync interval")
bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.hostname, "hostname", glDefaultDomain, "GitLab hostname") bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.hostname, "hostname", glDefaultDomain, "GitLab hostname")
bootstrapGitLabCmd.Flags().Var(&gitlabArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") bootstrapGitLabCmd.Flags().Var(&gitlabArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path")
@ -143,11 +133,6 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("--token-auth and --deploy-token-auth cannot be set both.") return fmt.Errorf("--token-auth and --deploy-token-auth cannot be set both.")
} }
if !gitlabArgs.private {
gitlabArgs.visibility.Set(string(gitprovider.RepositoryVisibilityPublic))
cmd.Println("Using visibility public as --private=false")
}
if err := bootstrapValidate(); err != nil { if err := bootstrapValidate(); err != nil {
return err return err
} }
@ -257,10 +242,10 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
if bootstrapArgs.tokenAuth { if bootstrapArgs.tokenAuth {
secretOpts.Username = "git" secretOpts.Username = "git"
secretOpts.Password = glToken secretOpts.Password = glToken
secretOpts.CACrt = caBundle secretOpts.CAFile = caBundle
} else if gitlabArgs.deployTokenAuth { } else if gitlabArgs.deployTokenAuth {
// the actual deploy token will be reconciled later // the actual deploy token will be reconciled later
secretOpts.CACrt = caBundle secretOpts.CAFile = caBundle
} else { } else {
keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password) keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password)
if err != nil { if err != nil {
@ -297,7 +282,6 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
// Bootstrap config // Bootstrap config
bootstrapOpts := []bootstrap.GitProviderOption{ bootstrapOpts := []bootstrap.GitProviderOption{
bootstrap.WithProviderRepository(gitlabArgs.owner, gitlabArgs.repository, gitlabArgs.personal), bootstrap.WithProviderRepository(gitlabArgs.owner, gitlabArgs.repository, gitlabArgs.personal),
bootstrap.WithProviderVisibility(gitlabArgs.visibility.String()),
bootstrap.WithBranch(bootstrapArgs.branch), bootstrap.WithBranch(bootstrapArgs.branch),
bootstrap.WithBootstrapTransportType("https"), bootstrap.WithBootstrapTransportType("https"),
bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail), bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail),
@ -317,6 +301,9 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
if gitlabArgs.deployTokenAuth { if gitlabArgs.deployTokenAuth {
bootstrapOpts = append(bootstrapOpts, bootstrap.WithDeployTokenAuth()) bootstrapOpts = append(bootstrapOpts, bootstrap.WithDeployTokenAuth())
} }
if !gitlabArgs.private {
bootstrapOpts = append(bootstrapOpts, bootstrap.WithProviderRepositoryConfig("", "", "public"))
}
if gitlabArgs.reconcile { if gitlabArgs.reconcile {
bootstrapOpts = append(bootstrapOpts, bootstrap.WithReconcile()) bootstrapOpts = append(bootstrapOpts, bootstrap.WithReconcile())
} }

@ -53,12 +53,7 @@ flux build kustomization my-app --path ./path/to/local/manifests \
# Exclude files by providing a comma separated list of entries that follow the .gitignore pattern fromat. # Exclude files by providing a comma separated list of entries that follow the .gitignore pattern fromat.
flux build kustomization my-app --path ./path/to/local/manifests \ flux build kustomization my-app --path ./path/to/local/manifests \
--kustomization-file ./path/to/local/my-app.yaml \ --kustomization-file ./path/to/local/my-app.yaml \
--ignore-paths "/to_ignore/**/*.yaml,ignore.yaml" --ignore-paths "/to_ignore/**/*.yaml,ignore.yaml"`,
# Run recursively on all encountered Kustomizations
flux build kustomization my-app --path ./path/to/local/manifests \
--recursive \
--local-sources GitRepository/flux-system/my-repo=./path/to/local/git`,
ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
RunE: buildKsCmdRun, RunE: buildKsCmdRun,
} }
@ -69,8 +64,6 @@ type buildKsFlags struct {
ignorePaths []string ignorePaths []string
dryRun bool dryRun bool
strictSubst bool strictSubst bool
recursive bool
localSources map[string]string
} }
var buildKsArgs buildKsFlags var buildKsArgs buildKsFlags
@ -82,8 +75,6 @@ func init() {
buildKsCmd.Flags().BoolVar(&buildKsArgs.dryRun, "dry-run", false, "Dry run mode.") buildKsCmd.Flags().BoolVar(&buildKsArgs.dryRun, "dry-run", false, "Dry run mode.")
buildKsCmd.Flags().BoolVar(&buildKsArgs.strictSubst, "strict-substitute", false, buildKsCmd.Flags().BoolVar(&buildKsArgs.strictSubst, "strict-substitute", false,
"When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.") "When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.")
buildKsCmd.Flags().BoolVarP(&buildKsArgs.recursive, "recursive", "r", false, "Recursively build Kustomizations")
buildKsCmd.Flags().StringToStringVar(&buildKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path")
buildCmd.AddCommand(buildKsCmd) buildCmd.AddCommand(buildKsCmd)
} }
@ -120,8 +111,6 @@ func buildKsCmdRun(cmd *cobra.Command, args []string) (err error) {
build.WithNamespace(*kubeconfigArgs.Namespace), build.WithNamespace(*kubeconfigArgs.Namespace),
build.WithIgnore(buildKsArgs.ignorePaths), build.WithIgnore(buildKsArgs.ignorePaths),
build.WithStrictSubstitute(buildKsArgs.strictSubst), build.WithStrictSubstitute(buildKsArgs.strictSubst),
build.WithRecursive(buildKsArgs.recursive),
build.WithLocalSources(buildKsArgs.localSources),
) )
} else { } else {
builder, err = build.NewBuilder(name, buildKsArgs.path, builder, err = build.NewBuilder(name, buildKsArgs.path,
@ -130,8 +119,6 @@ func buildKsCmdRun(cmd *cobra.Command, args []string) (err error) {
build.WithKustomizationFile(buildKsArgs.kustomizationFile), build.WithKustomizationFile(buildKsArgs.kustomizationFile),
build.WithIgnore(buildKsArgs.ignorePaths), build.WithIgnore(buildKsArgs.ignorePaths),
build.WithStrictSubstitute(buildKsArgs.strictSubst), build.WithStrictSubstitute(buildKsArgs.strictSubst),
build.WithRecursive(buildKsArgs.recursive),
build.WithLocalSources(buildKsArgs.localSources),
) )
} }

@ -22,7 +22,6 @@ package main
import ( import (
"bytes" "bytes"
"os" "os"
"path/filepath"
"testing" "testing"
"text/template" "text/template"
) )
@ -70,12 +69,6 @@ func TestBuildKustomization(t *testing.T) {
resultFile: "./testdata/build-kustomization/podinfo-with-ignore-result.yaml", resultFile: "./testdata/build-kustomization/podinfo-with-ignore-result.yaml",
assertFunc: "assertGoldenTemplateFile", assertFunc: "assertGoldenTemplateFile",
}, },
{
name: "build with recursive",
args: "build kustomization podinfo --path ./testdata/build-kustomization/podinfo-with-my-app --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization",
resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml",
assertFunc: "assertGoldenTemplateFile",
},
} }
tmpl := map[string]string{ tmpl := map[string]string{
@ -125,8 +118,6 @@ spec:
cluster_region: "eu-central-1" cluster_region: "eu-central-1"
` `
tmpFile := filepath.Join(t.TempDir(), "podinfo.yaml")
tests := []struct { tests := []struct {
name string name string
args string args string
@ -141,40 +132,28 @@ spec:
}, },
{ {
name: "build podinfo", name: "build podinfo",
args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/podinfo", args: "build kustomization podinfo --kustomization-file ./testdata/build-kustomization/podinfo.yaml --path ./testdata/build-kustomization/podinfo",
resultFile: "./testdata/build-kustomization/podinfo-result.yaml", resultFile: "./testdata/build-kustomization/podinfo-result.yaml",
assertFunc: "assertGoldenTemplateFile", assertFunc: "assertGoldenTemplateFile",
}, },
{ {
name: "build podinfo without service", name: "build podinfo without service",
args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/delete-service", args: "build kustomization podinfo --kustomization-file ./testdata/build-kustomization/podinfo.yaml --path ./testdata/build-kustomization/delete-service",
resultFile: "./testdata/build-kustomization/podinfo-without-service-result.yaml", resultFile: "./testdata/build-kustomization/podinfo-without-service-result.yaml",
assertFunc: "assertGoldenTemplateFile", assertFunc: "assertGoldenTemplateFile",
}, },
{ {
name: "build deployment and configmap with var substitution", name: "build deployment and configmap with var substitution",
args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/var-substitution", args: "build kustomization podinfo --kustomization-file ./testdata/build-kustomization/podinfo.yaml --path ./testdata/build-kustomization/var-substitution",
resultFile: "./testdata/build-kustomization/podinfo-with-var-substitution-result.yaml", resultFile: "./testdata/build-kustomization/podinfo-with-var-substitution-result.yaml",
assertFunc: "assertGoldenTemplateFile", assertFunc: "assertGoldenTemplateFile",
}, },
{ {
name: "build deployment and configmap with var substitution in dry-run mode", name: "build deployment and configmap with var substitution in dry-run mode",
args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/var-substitution --dry-run", args: "build kustomization podinfo --kustomization-file ./testdata/build-kustomization/podinfo.yaml --path ./testdata/build-kustomization/var-substitution --dry-run",
resultFile: "./testdata/build-kustomization/podinfo-with-var-substitution-result.yaml", resultFile: "./testdata/build-kustomization/podinfo-with-var-substitution-result.yaml",
assertFunc: "assertGoldenTemplateFile", assertFunc: "assertGoldenTemplateFile",
}, },
{
name: "build with recursive",
args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/podinfo-with-my-app --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization",
resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml",
assertFunc: "assertGoldenTemplateFile",
},
{
name: "build with recursive in dry-run mode",
args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/podinfo-with-my-app --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization --dry-run",
resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml",
assertFunc: "assertGoldenTemplateFile",
},
} }
tmpl := map[string]string{ tmpl := map[string]string{
@ -182,6 +161,8 @@ spec:
} }
setup(t, tmpl) setup(t, tmpl)
testEnv.CreateObjectFile("./testdata/build-kustomization/podinfo-source.yaml", tmpl, t)
temp, err := template.New("podinfo").Parse(podinfo) temp, err := template.New("podinfo").Parse(podinfo)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -193,10 +174,11 @@ spec:
t.Fatal(err) t.Fatal(err)
} }
err = os.WriteFile(tmpFile, b.Bytes(), 0666) err = os.WriteFile("./testdata/build-kustomization/podinfo.yaml", b.Bytes(), 0666)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Cleanup(func() { _ = os.Remove("./testdata/build-kustomization/podinfo.yaml") })
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

@ -60,7 +60,7 @@ type checkFlags struct {
} }
var kubernetesConstraints = []string{ var kubernetesConstraints = []string{
">=1.30.0-0", ">=1.28.0-0",
} }
var checkArgs checkFlags var checkArgs checkFlags

@ -125,7 +125,7 @@ func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) e
logger.Generatef("generating %s", names.kind) logger.Generatef("generating %s", names.kind)
logger.Actionf("applying %s", names.kind) logger.Actionf("applying %s", names.kind)
namespacedName, err := names.upsert(ctx, kubeClient, object, mutate) namespacedName, err := imageRepositoryType.upsert(ctx, kubeClient, object, mutate)
if err != nil { if err != nil {
return err return err
} }

@ -87,6 +87,7 @@ type secretGitFlags struct {
keyAlgorithm flags.PublicKeyAlgorithm keyAlgorithm flags.PublicKeyAlgorithm
rsaBits flags.RSAKeyBits rsaBits flags.RSAKeyBits
ecdsaCurve flags.ECDSACurve ecdsaCurve flags.ECDSACurve
caFile string
caCrtFile string caCrtFile string
privateKeyFile string privateKeyFile string
bearerToken string bearerToken string
@ -101,7 +102,8 @@ func init() {
createSecretGitCmd.Flags().Var(&secretGitArgs.keyAlgorithm, "ssh-key-algorithm", secretGitArgs.keyAlgorithm.Description()) createSecretGitCmd.Flags().Var(&secretGitArgs.keyAlgorithm, "ssh-key-algorithm", secretGitArgs.keyAlgorithm.Description())
createSecretGitCmd.Flags().Var(&secretGitArgs.rsaBits, "ssh-rsa-bits", secretGitArgs.rsaBits.Description()) createSecretGitCmd.Flags().Var(&secretGitArgs.rsaBits, "ssh-rsa-bits", secretGitArgs.rsaBits.Description())
createSecretGitCmd.Flags().Var(&secretGitArgs.ecdsaCurve, "ssh-ecdsa-curve", secretGitArgs.ecdsaCurve.Description()) createSecretGitCmd.Flags().Var(&secretGitArgs.ecdsaCurve, "ssh-ecdsa-curve", secretGitArgs.ecdsaCurve.Description())
createSecretGitCmd.Flags().StringVar(&secretGitArgs.caCrtFile, "ca-crt-file", "", "path to TLS CA certificate file used for validating self-signed certificates") createSecretGitCmd.Flags().StringVar(&secretGitArgs.caFile, "ca-file", "", "path to TLS CA file used for validating self-signed certificates")
createSecretGitCmd.Flags().StringVar(&secretGitArgs.caCrtFile, "ca-crt-file", "", "path to TLS CA certificate file used for validating self-signed certificates; takes precedence over --ca-file")
createSecretGitCmd.Flags().StringVar(&secretGitArgs.privateKeyFile, "private-key-file", "", "path to a passwordless private key file used for authenticating to the Git SSH server") createSecretGitCmd.Flags().StringVar(&secretGitArgs.privateKeyFile, "private-key-file", "", "path to a passwordless private key file used for authenticating to the Git SSH server")
createSecretGitCmd.Flags().StringVar(&secretGitArgs.bearerToken, "bearer-token", "", "bearer authentication token") createSecretGitCmd.Flags().StringVar(&secretGitArgs.bearerToken, "bearer-token", "", "bearer authentication token")
@ -167,6 +169,11 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return fmt.Errorf("unable to read TLS CA file: %w", err) return fmt.Errorf("unable to read TLS CA file: %w", err)
} }
} else if secretGitArgs.caFile != "" {
opts.CAFile, err = os.ReadFile(secretGitArgs.caFile)
if err != nil {
return fmt.Errorf("unable to read TLS CA file: %w", err)
}
} }
default: default:
return fmt.Errorf("git URL scheme '%s' not supported, can be: ssh, http and https", u.Scheme) return fmt.Errorf("git URL scheme '%s' not supported, can be: ssh, http and https", u.Scheme)

@ -1,128 +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 main
import (
"context"
"fmt"
"os"
"github.com/fluxcd/flux2/v2/internal/utils"
"github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/yaml"
)
var createSecretGitHubAppCmd = &cobra.Command{
Use: "githubapp [name]",
Short: "Create or update a github app secret",
Long: withPreviewNote(`The create secret githubapp command generates a Kubernetes secret that can be used for GitRepository authentication with github app`),
Example: ` # Create a githubapp authentication secret on disk and encrypt it with Mozilla SOPS
flux create secret githubapp podinfo-auth \
--app-id="1" \
--app-installation-id="2" \
--app-private-key=./private-key-file.pem \
--export > githubapp-auth.yaml
sops --encrypt --encrypted-regex '^(data|stringData)$' \
--in-place githubapp-auth.yaml
`,
RunE: createSecretGitHubAppCmdRun,
}
type secretGitHubAppFlags struct {
appID string
appInstallationID string
privateKeyFile string
baseURL string
}
var secretGitHubAppArgs = secretGitHubAppFlags{}
func init() {
createSecretGitHubAppCmd.Flags().StringVar(&secretGitHubAppArgs.appID, "app-id", "", "github app ID")
createSecretGitHubAppCmd.Flags().StringVar(&secretGitHubAppArgs.appInstallationID, "app-installation-id", "", "github app installation ID")
createSecretGitHubAppCmd.Flags().StringVar(&secretGitHubAppArgs.privateKeyFile, "app-private-key", "", "github app private key file path")
createSecretGitHubAppCmd.Flags().StringVar(&secretGitHubAppArgs.baseURL, "app-base-url", "", "github app base URL")
createSecretCmd.AddCommand(createSecretGitHubAppCmd)
}
func createSecretGitHubAppCmdRun(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("name is required")
}
secretName := args[0]
if secretGitHubAppArgs.appID == "" {
return fmt.Errorf("--app-id is required")
}
if secretGitHubAppArgs.appInstallationID == "" {
return fmt.Errorf("--app-installation-id is required")
}
if secretGitHubAppArgs.privateKeyFile == "" {
return fmt.Errorf("--app-private-key is required")
}
privateKey, err := os.ReadFile(secretGitHubAppArgs.privateKeyFile)
if err != nil {
return fmt.Errorf("unable to read private key file: %w", err)
}
opts := sourcesecret.Options{
Name: secretName,
Namespace: *kubeconfigArgs.Namespace,
GitHubAppID: secretGitHubAppArgs.appID,
GitHubAppInstallationID: secretGitHubAppArgs.appInstallationID,
GitHubAppPrivateKey: string(privateKey),
}
if secretGitHubAppArgs.baseURL != "" {
opts.GitHubAppBaseURL = secretGitHubAppArgs.baseURL
}
secret, err := sourcesecret.Generate(opts)
if err != nil {
return err
}
if createArgs.export {
rootCmd.Println(secret.Content)
return nil
}
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return err
}
var s corev1.Secret
if err := yaml.Unmarshal([]byte(secret.Content), &s); err != nil {
return err
}
if err := upsertSecret(ctx, kubeClient, s); err != nil {
return err
}
logger.Actionf("githubapp secret '%s' created in '%s' namespace", secretName, *kubeconfigArgs.Namespace)
return nil
}

@ -1,74 +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 main
import (
"testing"
)
func TestCreateSecretGitHubApp(t *testing.T) {
tests := []struct {
name string
args string
assert assertFunc
}{
{
name: "create githubapp secret with missing name",
args: "create secret githubapp",
assert: assertError("name is required"),
},
{
name: "create githubapp secret with missing app-id",
args: "create secret githubapp appinfo",
assert: assertError("--app-id is required"),
},
{
name: "create githubapp secret with missing appInstallationID",
args: "create secret githubapp appinfo --app-id 1",
assert: assertError("--app-installation-id is required"),
},
{
name: "create githubapp secret with missing private key file",
args: "create secret githubapp appinfo --app-id 1 --app-installation-id 2",
assert: assertError("--app-private-key is required"),
},
{
name: "create githubapp secret with private key file that does not exist",
args: "create secret githubapp appinfo --app-id 1 --app-installation-id 2 --app-private-key pk.pem",
assert: assertError("unable to read private key file: open pk.pem: no such file or directory"),
},
{
name: "create githubapp secret with app info",
args: "create secret githubapp appinfo --namespace my-namespace --app-id 1 --app-installation-id 2 --app-private-key ./testdata/create_secret/githubapp/test-private-key.pem --export",
assert: assertGoldenFile("testdata/create_secret/githubapp/secret.yaml"),
},
{
name: "create githubapp secret with appinfo and base url",
args: "create secret githubapp appinfo --namespace my-namespace --app-id 1 --app-installation-id 2 --app-private-key ./testdata/create_secret/githubapp/test-private-key.pem --app-base-url www.example.com/api/v3 --export",
assert: assertGoldenFile("testdata/create_secret/githubapp/secret-with-baseurl.yaml"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := cmdTestCase{
args: tt.args,
assert: tt.assert,
}
cmd.runTestCmd(t)
})
}
}

@ -58,9 +58,12 @@ func init() {
flags := createSecretHelmCmd.Flags() flags := createSecretHelmCmd.Flags()
flags.StringVarP(&secretHelmArgs.username, "username", "u", "", "basic authentication username") flags.StringVarP(&secretHelmArgs.username, "username", "u", "", "basic authentication username")
flags.StringVarP(&secretHelmArgs.password, "password", "p", "", "basic authentication password") flags.StringVarP(&secretHelmArgs.password, "password", "p", "", "basic authentication password")
flags.StringVar(&secretHelmArgs.tlsCrtFile, "tls-crt-file", "", "TLS authentication cert file path")
flags.StringVar(&secretHelmArgs.tlsKeyFile, "tls-key-file", "", "TLS authentication key file path") initSecretDeprecatedTLSFlags(flags, &secretHelmArgs.secretTLSFlags)
flags.StringVar(&secretHelmArgs.caCrtFile, "ca-crt-file", "", "TLS authentication CA file path") deprecationMsg := "please use the command `flux create secret tls` to generate TLS secrets"
flags.MarkDeprecated("cert-file", deprecationMsg)
flags.MarkDeprecated("key-file", deprecationMsg)
flags.MarkDeprecated("ca-file", deprecationMsg)
createSecretCmd.AddCommand(createSecretHelmCmd) createSecretCmd.AddCommand(createSecretHelmCmd)
} }
@ -74,20 +77,20 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error {
} }
caBundle := []byte{} caBundle := []byte{}
if secretHelmArgs.caCrtFile != "" { if secretHelmArgs.caFile != "" {
var err error var err error
caBundle, err = os.ReadFile(secretHelmArgs.caCrtFile) caBundle, err = os.ReadFile(secretHelmArgs.caFile)
if err != nil { if err != nil {
return fmt.Errorf("unable to read TLS CA file: %w", err) return fmt.Errorf("unable to read TLS CA file: %w", err)
} }
} }
var certFile, keyFile []byte var certFile, keyFile []byte
if secretHelmArgs.tlsCrtFile != "" && secretHelmArgs.tlsKeyFile != "" { if secretHelmArgs.certFile != "" && secretHelmArgs.keyFile != "" {
if certFile, err = os.ReadFile(secretHelmArgs.tlsCrtFile); err != nil { if certFile, err = os.ReadFile(secretHelmArgs.certFile); err != nil {
return fmt.Errorf("failed to read cert file: %w", err) return fmt.Errorf("failed to read cert file: %w", err)
} }
if keyFile, err = os.ReadFile(secretHelmArgs.tlsKeyFile); err != nil { if keyFile, err = os.ReadFile(secretHelmArgs.keyFile); err != nil {
return fmt.Errorf("failed to read key file: %w", err) return fmt.Errorf("failed to read key file: %w", err)
} }
} }
@ -98,9 +101,9 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error {
Labels: labels, Labels: labels,
Username: secretHelmArgs.username, Username: secretHelmArgs.username,
Password: secretHelmArgs.password, Password: secretHelmArgs.password,
CACrt: caBundle, CAFile: caBundle,
TLSCrt: certFile, CertFile: certFile,
TLSKey: keyFile, KeyFile: keyFile,
} }
secret, err := sourcesecret.Generate(opts) secret, err := sourcesecret.Generate(opts)
if err != nil { if err != nil {

@ -84,7 +84,7 @@ func TestCreateNotationSecret(t *testing.T) {
{ {
name: "invalid trust policy", name: "invalid trust policy",
args: fmt.Sprintf("create secret notation notation-config --ca-cert-file=%s --trust-policy-file=%s", t.TempDir(), invalidTrustPolicy), args: fmt.Sprintf("create secret notation notation-config --ca-cert-file=%s --trust-policy-file=%s", t.TempDir(), invalidTrustPolicy),
assert: assertError("invalid trust policy: trust policy: a trust policy statement is missing a name, every statement requires a name"), assert: assertError("invalid trust policy: a trust policy statement is missing a name, every statement requires a name"),
}, },
{ {
name: "invalid trust policy json", name: "invalid trust policy json",

@ -1,112 +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 main
import (
"context"
"errors"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/yaml"
"github.com/fluxcd/flux2/v2/internal/utils"
"github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret"
)
var createSecretProxyCmd = &cobra.Command{
Use: "proxy [name]",
Short: "Create or update a Kubernetes secret for proxy authentication",
Long: `The create secret proxy command generates a Kubernetes secret with the
proxy address and the basic authentication credentials.`,
Example: ` # Create a proxy secret on disk and encrypt it with SOPS
flux create secret proxy my-proxy \
--namespace=my-namespace \
--address=https://my-proxy.com \
--username=my-username \
--password=my-password \
--export > proxy.yaml
sops --encrypt --encrypted-regex '^(data|stringData)$' \
--in-place proxy.yaml`,
RunE: createSecretProxyCmdRun,
}
type secretProxyFlags struct {
address string
username string
password string
}
var secretProxyArgs secretProxyFlags
func init() {
createSecretProxyCmd.Flags().StringVar(&secretProxyArgs.address, "address", "", "proxy address")
createSecretProxyCmd.Flags().StringVarP(&secretProxyArgs.username, "username", "u", "", "basic authentication username")
createSecretProxyCmd.Flags().StringVarP(&secretProxyArgs.password, "password", "p", "", "basic authentication password")
createSecretCmd.AddCommand(createSecretProxyCmd)
}
func createSecretProxyCmdRun(cmd *cobra.Command, args []string) error {
name := args[0]
labels, err := parseLabels()
if err != nil {
return err
}
if secretProxyArgs.address == "" {
return errors.New("address is required")
}
opts := sourcesecret.Options{
Name: name,
Namespace: *kubeconfigArgs.Namespace,
Labels: labels,
Address: secretProxyArgs.address,
Username: secretProxyArgs.username,
Password: secretProxyArgs.password,
}
secret, err := sourcesecret.Generate(opts)
if err != nil {
return err
}
if createArgs.export {
rootCmd.Println(secret.Content)
return nil
}
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return err
}
var s corev1.Secret
if err := yaml.Unmarshal([]byte(secret.Content), &s); err != nil {
return err
}
if err := upsertSecret(ctx, kubeClient, s); err != nil {
return err
}
logger.Actionf("proxy secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace)
return nil
}

@ -1,47 +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 main
import (
"testing"
)
func TestCreateProxySecret(t *testing.T) {
tests := []struct {
name string
args string
assert assertFunc
}{
{
args: "create secret proxy proxy-secret",
assert: assertError("address is required"),
},
{
args: "create secret proxy proxy-secret --address=https://my-proxy.com --username=my-username --password=my-password --namespace=my-namespace --export",
assert: assertGoldenFile("testdata/create_secret/proxy/secret-proxy.yaml"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := cmdTestCase{
args: tt.args,
assert: tt.assert,
}
cmd.runTestCmd(t)
})
}
}

@ -22,6 +22,7 @@ import (
"os" "os"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
@ -32,8 +33,8 @@ import (
var createSecretTLSCmd = &cobra.Command{ var createSecretTLSCmd = &cobra.Command{
Use: "tls [name]", Use: "tls [name]",
Short: "Create or update a Kubernetes secret with TLS certificates", Short: "Create or update a Kubernetes secret with TLS certificates",
Long: `The create secret tls command generates a Kubernetes secret with certificates for use with TLS.`, Long: withPreviewNote(`The create secret tls command generates a Kubernetes secret with certificates for use with TLS.`),
Example: ` # Create a TLS secret on disk and encrypt it with SOPS. Example: ` # Create a TLS secret on disk and encrypt it with Mozilla SOPS.
# Files are expected to be PEM-encoded. # Files are expected to be PEM-encoded.
flux create secret tls certs \ flux create secret tls certs \
--namespace=my-namespace \ --namespace=my-namespace \
@ -48,6 +49,9 @@ var createSecretTLSCmd = &cobra.Command{
} }
type secretTLSFlags struct { type secretTLSFlags struct {
certFile string
keyFile string
caFile string
caCrtFile string caCrtFile string
tlsKeyFile string tlsKeyFile string
tlsCrtFile string tlsCrtFile string
@ -55,10 +59,26 @@ type secretTLSFlags struct {
var secretTLSArgs secretTLSFlags var secretTLSArgs secretTLSFlags
func initSecretDeprecatedTLSFlags(flags *pflag.FlagSet, args *secretTLSFlags) {
flags.StringVar(&args.certFile, "cert-file", "", "TLS authentication cert file path")
flags.StringVar(&args.keyFile, "key-file", "", "TLS authentication key file path")
flags.StringVar(&args.caFile, "ca-file", "", "TLS authentication CA file path")
}
func initSecretTLSFlags(flags *pflag.FlagSet, args *secretTLSFlags) {
flags.StringVar(&args.tlsCrtFile, "tls-crt-file", "", "TLS authentication cert file path")
flags.StringVar(&args.tlsKeyFile, "tls-key-file", "", "TLS authentication key file path")
flags.StringVar(&args.caCrtFile, "ca-crt-file", "", "TLS authentication CA file path")
}
func init() { func init() {
createSecretTLSCmd.Flags().StringVar(&secretTLSArgs.tlsCrtFile, "tls-crt-file", "", "TLS authentication cert file path") flags := createSecretTLSCmd.Flags()
createSecretTLSCmd.Flags().StringVar(&secretTLSArgs.tlsKeyFile, "tls-key-file", "", "TLS authentication key file path") initSecretDeprecatedTLSFlags(flags, &secretTLSArgs)
createSecretTLSCmd.Flags().StringVar(&secretTLSArgs.caCrtFile, "ca-crt-file", "", "TLS authentication CA file path") initSecretTLSFlags(flags, &secretTLSArgs)
flags.MarkDeprecated("cert-file", "please use --tls-crt-file instead")
flags.MarkDeprecated("key-file", "please use --tls-key-file instead")
flags.MarkDeprecated("ca-file", "please use --ca-crt-file instead")
createSecretCmd.AddCommand(createSecretTLSCmd) createSecretCmd.AddCommand(createSecretTLSCmd)
} }
@ -82,6 +102,11 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return fmt.Errorf("unable to read TLS CA file: %w", err) return fmt.Errorf("unable to read TLS CA file: %w", err)
} }
} else if secretTLSArgs.caFile != "" {
opts.CAFile, err = os.ReadFile(secretTLSArgs.caFile)
if err != nil {
return fmt.Errorf("unable to read TLS CA file: %w", err)
}
} }
if secretTLSArgs.tlsCrtFile != "" && secretTLSArgs.tlsKeyFile != "" { if secretTLSArgs.tlsCrtFile != "" && secretTLSArgs.tlsKeyFile != "" {
@ -91,6 +116,13 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error {
if opts.TLSKey, err = os.ReadFile(secretTLSArgs.tlsKeyFile); err != nil { if opts.TLSKey, err = os.ReadFile(secretTLSArgs.tlsKeyFile); err != nil {
return fmt.Errorf("failed to read key file: %w", err) return fmt.Errorf("failed to read key file: %w", err)
} }
} else if secretTLSArgs.certFile != "" && secretTLSArgs.keyFile != "" {
if opts.CertFile, err = os.ReadFile(secretTLSArgs.certFile); err != nil {
return fmt.Errorf("failed to read cert file: %w", err)
}
if opts.KeyFile, err = os.ReadFile(secretTLSArgs.keyFile); err != nil {
return fmt.Errorf("failed to read key file: %w", err)
}
} }
secret, err := sourcesecret.Generate(opts) secret, err := sourcesecret.Generate(opts)

@ -18,6 +18,10 @@ func TestCreateTlsSecret(t *testing.T) {
args: "create secret tls certs --namespace=my-namespace --tls-crt-file=./testdata/create_secret/tls/test-cert.pem --tls-key-file=./testdata/create_secret/tls/test-key.pem --ca-crt-file=./testdata/create_secret/tls/test-ca.pem --export", args: "create secret tls certs --namespace=my-namespace --tls-crt-file=./testdata/create_secret/tls/test-cert.pem --tls-key-file=./testdata/create_secret/tls/test-key.pem --ca-crt-file=./testdata/create_secret/tls/test-ca.pem --export",
assert: assertGoldenFile("testdata/create_secret/tls/secret-tls.yaml"), assert: assertGoldenFile("testdata/create_secret/tls/secret-tls.yaml"),
}, },
{
args: "create secret tls certs --namespace=my-namespace --cert-file=./testdata/create_secret/tls/test-cert.pem --key-file=./testdata/create_secret/tls/test-key.pem --ca-file=./testdata/create_secret/tls/test-ca.pem --export",
assert: assertGoldenFile("testdata/create_secret/tls/deprecated-secret-tls.yaml"),
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

@ -32,7 +32,7 @@ import (
"github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/flux2/v2/internal/flags" "github.com/fluxcd/flux2/v2/internal/flags"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
@ -41,8 +41,8 @@ import (
var createSourceBucketCmd = &cobra.Command{ var createSourceBucketCmd = &cobra.Command{
Use: "bucket [name]", Use: "bucket [name]",
Short: "Create or update a Bucket source", Short: "Create or update a Bucket source",
Long: `The create source bucket command generates a Bucket resource and waits for it to be downloaded. Long: withPreviewNote(`The create source bucket command generates a Bucket resource and waits for it to be downloaded.
For Buckets with static authentication, the credentials are stored in a Kubernetes secret.`, For Buckets with static authentication, the credentials are stored in a Kubernetes secret.`),
Example: ` # Create a source for a Bucket using static authentication Example: ` # Create a source for a Bucket using static authentication
flux create source bucket podinfo \ flux create source bucket podinfo \
--bucket-name=podinfo \ --bucket-name=podinfo \
@ -71,7 +71,6 @@ type sourceBucketFlags struct {
region string region string
insecure bool insecure bool
secretRef string secretRef string
proxySecretRef string
ignorePaths []string ignorePaths []string
} }
@ -86,7 +85,6 @@ func init() {
createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.region, "region", "", "the bucket region") createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.region, "region", "", "the bucket region")
createSourceBucketCmd.Flags().BoolVar(&sourceBucketArgs.insecure, "insecure", false, "for when connecting to a non-TLS S3 HTTP endpoint") createSourceBucketCmd.Flags().BoolVar(&sourceBucketArgs.insecure, "insecure", false, "for when connecting to a non-TLS S3 HTTP endpoint")
createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.secretRef, "secret-ref", "", "the name of an existing secret containing credentials") createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.secretRef, "secret-ref", "", "the name of an existing secret containing credentials")
createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.proxySecretRef, "proxy-secret-ref", "", "the name of an existing secret containing the proxy address and credentials")
createSourceBucketCmd.Flags().StringSliceVar(&sourceBucketArgs.ignorePaths, "ignore-paths", nil, "set paths to ignore in bucket resource (can specify multiple paths with commas: path1,path2)") createSourceBucketCmd.Flags().StringSliceVar(&sourceBucketArgs.ignorePaths, "ignore-paths", nil, "set paths to ignore in bucket resource (can specify multiple paths with commas: path1,path2)")
createSourceCmd.AddCommand(createSourceBucketCmd) createSourceCmd.AddCommand(createSourceBucketCmd)
@ -94,7 +92,7 @@ func init() {
func newSourceBucketFlags() sourceBucketFlags { func newSourceBucketFlags() sourceBucketFlags {
return sourceBucketFlags{ return sourceBucketFlags{
provider: flags.SourceBucketProvider(sourcev1.BucketProviderGeneric), provider: flags.SourceBucketProvider(sourcev1.GenericBucketProvider),
} }
} }
@ -155,12 +153,6 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
} }
} }
if sourceBucketArgs.proxySecretRef != "" {
bucket.Spec.ProxySecretRef = &meta.LocalObjectReference{
Name: sourceBucketArgs.proxySecretRef,
}
}
if createArgs.export { if createArgs.export {
return printExport(exportBucket(bucket)) return printExport(exportBucket(bucket))
} }

@ -56,8 +56,6 @@ type sourceGitFlags struct {
keyRSABits flags.RSAKeyBits keyRSABits flags.RSAKeyBits
keyECDSACurve flags.ECDSACurve keyECDSACurve flags.ECDSACurve
secretRef string secretRef string
proxySecretRef string
provider flags.SourceGitProvider
caFile string caFile string
privateKeyFile string privateKeyFile string
recurseSubmodules bool recurseSubmodules bool
@ -121,13 +119,7 @@ For private Git repositories, the basic authentication credentials are stored in
--url=https://github.com/stefanprodan/podinfo \ --url=https://github.com/stefanprodan/podinfo \
--branch=master \ --branch=master \
--username=username \ --username=username \
--password=password --password=password`,
# Create a source for a Git repository using azure provider
flux create source git podinfo \
--url=https://dev.azure.com/foo/bar/_git/podinfo \
--branch=master \
--provider=azure`,
RunE: createSourceGitCmdRun, RunE: createSourceGitCmdRun,
} }
@ -145,9 +137,7 @@ func init() {
createSourceGitCmd.Flags().Var(&sourceGitArgs.keyAlgorithm, "ssh-key-algorithm", sourceGitArgs.keyAlgorithm.Description()) createSourceGitCmd.Flags().Var(&sourceGitArgs.keyAlgorithm, "ssh-key-algorithm", sourceGitArgs.keyAlgorithm.Description())
createSourceGitCmd.Flags().Var(&sourceGitArgs.keyRSABits, "ssh-rsa-bits", sourceGitArgs.keyRSABits.Description()) createSourceGitCmd.Flags().Var(&sourceGitArgs.keyRSABits, "ssh-rsa-bits", sourceGitArgs.keyRSABits.Description())
createSourceGitCmd.Flags().Var(&sourceGitArgs.keyECDSACurve, "ssh-ecdsa-curve", sourceGitArgs.keyECDSACurve.Description()) createSourceGitCmd.Flags().Var(&sourceGitArgs.keyECDSACurve, "ssh-ecdsa-curve", sourceGitArgs.keyECDSACurve.Description())
createSourceGitCmd.Flags().StringVar(&sourceGitArgs.secretRef, "secret-ref", "", "the name of an existing secret containing SSH or basic credentials or github app authentication") createSourceGitCmd.Flags().StringVar(&sourceGitArgs.secretRef, "secret-ref", "", "the name of an existing secret containing SSH or basic credentials")
createSourceGitCmd.Flags().StringVar(&sourceGitArgs.proxySecretRef, "proxy-secret-ref", "", "the name of an existing secret containing the proxy address and credentials")
createSourceGitCmd.Flags().Var(&sourceGitArgs.provider, "provider", sourceGitArgs.provider.Description())
createSourceGitCmd.Flags().StringVar(&sourceGitArgs.caFile, "ca-file", "", "path to TLS CA file used for validating self-signed certificates") createSourceGitCmd.Flags().StringVar(&sourceGitArgs.caFile, "ca-file", "", "path to TLS CA file used for validating self-signed certificates")
createSourceGitCmd.Flags().StringVar(&sourceGitArgs.privateKeyFile, "private-key-file", "", "path to a passwordless private key file used for authenticating to the Git SSH server") createSourceGitCmd.Flags().StringVar(&sourceGitArgs.privateKeyFile, "private-key-file", "", "path to a passwordless private key file used for authenticating to the Git SSH server")
createSourceGitCmd.Flags().BoolVar(&sourceGitArgs.recurseSubmodules, "recurse-submodules", false, createSourceGitCmd.Flags().BoolVar(&sourceGitArgs.recurseSubmodules, "recurse-submodules", false,
@ -246,16 +236,6 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
} }
} }
if sourceGitArgs.proxySecretRef != "" {
gitRepository.Spec.ProxySecretRef = &meta.LocalObjectReference{
Name: sourceGitArgs.proxySecretRef,
}
}
if provider := sourceGitArgs.provider.String(); provider != "" {
gitRepository.Spec.Provider = provider
}
if createArgs.export { if createArgs.export {
return printExport(exportGit(&gitRepository)) return printExport(exportGit(&gitRepository))
} }
@ -293,7 +273,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return fmt.Errorf("unable to read TLS CA file: %w", err) return fmt.Errorf("unable to read TLS CA file: %w", err)
} }
secretOpts.CACrt = caBundle secretOpts.CAFile = caBundle
} }
secretOpts.Username = sourceGitArgs.username secretOpts.Username = sourceGitArgs.username
secretOpts.Password = sourceGitArgs.password secretOpts.Password = sourceGitArgs.password

@ -134,36 +134,6 @@ func TestCreateSourceGitExport(t *testing.T) {
args: "create source git podinfo --namespace=flux-system --url=https://github.com/stefanprodan/podinfo --branch=test --interval=1m0s --export", args: "create source git podinfo --namespace=flux-system --url=https://github.com/stefanprodan/podinfo --branch=test --interval=1m0s --export",
assert: assertGoldenFile("testdata/create_source_git/source-git-branch.yaml"), assert: assertGoldenFile("testdata/create_source_git/source-git-branch.yaml"),
}, },
{
name: "source with generic provider",
args: "create source git podinfo --namespace=flux-system --url=https://github.com/stefanprodan/podinfo --provider generic --branch=test --interval=1m0s --export",
assert: assertGoldenFile("testdata/create_source_git/source-git-provider-generic.yaml"),
},
{
name: "source with azure provider",
args: "create source git podinfo --namespace=flux-system --url=https://dev.azure.com/foo/bar/_git/podinfo --provider azure --branch=test --interval=1m0s --export",
assert: assertGoldenFile("testdata/create_source_git/source-git-provider-azure.yaml"),
},
{
name: "source with github provider",
args: "create source git podinfo --namespace=flux-system --url=https://github.com/stefanprodan/podinfo --provider github --branch=test --interval=1m0s --secret-ref appinfo --export",
assert: assertGoldenFile("testdata/create_source_git/source-git-provider-github.yaml"),
},
{
name: "source with invalid provider",
args: "create source git podinfo --namespace=flux-system --url=https://dev.azure.com/foo/bar/_git/podinfo --provider dummy --branch=test --interval=1m0s --export",
assert: assertError("invalid argument \"dummy\" for \"--provider\" flag: source Git provider 'dummy' is not supported, must be one of: generic|azure|github"),
},
{
name: "source with empty provider",
args: "create source git podinfo --namespace=flux-system --url=https://dev.azure.com/foo/bar/_git/podinfo --provider \"\" --branch=test --interval=1m0s --export",
assert: assertError("invalid argument \"\" for \"--provider\" flag: no source Git provider given, please specify the Git provider name"),
},
{
name: "source with no provider",
args: "create source git podinfo --namespace=flux-system --url=https://dev.azure.com/foo/bar/_git/podinfo --branch=test --interval=1m0s --export --provider",
assert: assertError("flag needs an argument: --provider"),
},
} }
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {

@ -197,9 +197,9 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
Namespace: *kubeconfigArgs.Namespace, Namespace: *kubeconfigArgs.Namespace,
Username: sourceHelmArgs.username, Username: sourceHelmArgs.username,
Password: sourceHelmArgs.password, Password: sourceHelmArgs.password,
CACrt: caBundle, CAFile: caBundle,
TLSCrt: certFile, CertFile: certFile,
TLSKey: keyFile, KeyFile: keyFile,
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
} }
secret, err := sourcesecret.Generate(secretOpts) secret, err := sourcesecret.Generate(secretOpts)

@ -65,7 +65,6 @@ type sourceOCIRepositoryFlags struct {
semver string semver string
digest string digest string
secretRef string secretRef string
proxySecretRef string
serviceAccount string serviceAccount string
certSecretRef string certSecretRef string
verifyProvider flags.SourceOCIVerifyProvider verifyProvider flags.SourceOCIVerifyProvider
@ -92,7 +91,6 @@ func init() {
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.semver, "tag-semver", "", "the OCI artifact tag semver range") createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.semver, "tag-semver", "", "the OCI artifact tag semver range")
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.digest, "digest", "", "the OCI artifact digest") createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.digest, "digest", "", "the OCI artifact digest")
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.secretRef, "secret-ref", "", "the name of the Kubernetes image pull secret (type 'kubernetes.io/dockerconfigjson')") createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.secretRef, "secret-ref", "", "the name of the Kubernetes image pull secret (type 'kubernetes.io/dockerconfigjson')")
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.proxySecretRef, "proxy-secret-ref", "", "the name of an existing secret containing the proxy address and credentials")
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.serviceAccount, "service-account", "", "the name of the Kubernetes service account that refers to an image pull secret") createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.serviceAccount, "service-account", "", "the name of the Kubernetes service account that refers to an image pull secret")
createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.certSecretRef, "cert-ref", "", "the name of a secret to use for TLS certificates") createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.certSecretRef, "cert-ref", "", "the name of a secret to use for TLS certificates")
createSourceOCIRepositoryCmd.Flags().Var(&sourceOCIRepositoryArgs.verifyProvider, "verify-provider", sourceOCIRepositoryArgs.verifyProvider.Description()) createSourceOCIRepositoryCmd.Flags().Var(&sourceOCIRepositoryArgs.verifyProvider, "verify-provider", sourceOCIRepositoryArgs.verifyProvider.Description())
@ -169,12 +167,6 @@ func createSourceOCIRepositoryCmdRun(cmd *cobra.Command, args []string) error {
} }
} }
if secretName := sourceOCIRepositoryArgs.proxySecretRef; secretName != "" {
repository.Spec.ProxySecretRef = &meta.LocalObjectReference{
Name: secretName,
}
}
if secretName := sourceOCIRepositoryArgs.certSecretRef; secretName != "" { if secretName := sourceOCIRepositoryArgs.certSecretRef; secretName != "" {
repository.Spec.CertSecretRef = &meta.LocalObjectReference{ repository.Spec.CertSecretRef = &meta.LocalObjectReference{
Name: secretName, Name: secretName,

@ -1,31 +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 main
import (
"github.com/spf13/cobra"
)
var debugCmd = &cobra.Command{
Use: "debug",
Short: "Debug a flux resource",
Long: `The debug command can be used to troubleshoot failing resource reconciliations.`,
}
func init() {
rootCmd.AddCommand(debugCmd)
}

@ -1,113 +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 main
import (
"context"
"fmt"
helmv2 "github.com/fluxcd/helm-controller/api/v2"
"github.com/fluxcd/pkg/chartutil"
"github.com/go-logr/logr"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/yaml"
"github.com/fluxcd/flux2/v2/internal/utils"
)
var debugHelmReleaseCmd = &cobra.Command{
Use: "helmrelease [name]",
Aliases: []string{"hr"},
Short: "Debug a HelmRelease resource",
Long: withPreviewNote(`The debug helmrelease command can be used to troubleshoot failing Helm release reconciliations.
WARNING: This command will print sensitive information if Kubernetes Secrets are referenced in the HelmRelease .spec.valuesFrom field.`),
Example: ` # Print the status of a Helm release
flux debug hr podinfo --show-status
# Export the final values of a Helm release composed from referred ConfigMaps and Secrets
flux debug hr podinfo --show-values > values.yaml`,
RunE: debugHelmReleaseCmdRun,
Args: cobra.ExactArgs(1),
ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)),
}
type debugHelmReleaseFlags struct {
showStatus bool
showValues bool
}
var debugHelmReleaseArgs debugHelmReleaseFlags
func init() {
debugHelmReleaseCmd.Flags().BoolVar(&debugHelmReleaseArgs.showStatus, "show-status", false, "print the status of the Helm release")
debugHelmReleaseCmd.Flags().BoolVar(&debugHelmReleaseArgs.showValues, "show-values", false, "print the final values of the Helm release")
debugCmd.AddCommand(debugHelmReleaseCmd)
}
func debugHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
name := args[0]
if (!debugHelmReleaseArgs.showStatus && !debugHelmReleaseArgs.showValues) ||
(debugHelmReleaseArgs.showStatus && debugHelmReleaseArgs.showValues) {
return fmt.Errorf("either --show-status or --show-values must be set")
}
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return err
}
hr := &helmv2.HelmRelease{}
hrName := types.NamespacedName{Namespace: *kubeconfigArgs.Namespace, Name: name}
if err := kubeClient.Get(ctx, hrName, hr); err != nil {
return err
}
if debugHelmReleaseArgs.showStatus {
status, err := yaml.Marshal(hr.Status)
if err != nil {
return err
}
rootCmd.Println("# Status documentation: https://fluxcd.io/flux/components/helm/helmreleases/#helmrelease-status")
rootCmd.Print(string(status))
return nil
}
if debugHelmReleaseArgs.showValues {
finalValues, err := chartutil.ChartValuesFromReferences(ctx,
logr.Discard(),
kubeClient,
hr.GetNamespace(),
hr.GetValues(),
hr.Spec.ValuesFrom...)
if err != nil {
return err
}
values, err := yaml.Marshal(finalValues)
if err != nil {
return err
}
rootCmd.Print(string(values))
}
return nil
}

@ -1,71 +0,0 @@
//go:build unit
// +build unit
/*
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 main
import (
"testing"
)
func TestDebugHelmRelease(t *testing.T) {
namespace := allocateNamespace("debug")
objectFile := "testdata/debug_helmrelease/objects.yaml"
tmpl := map[string]string{
"fluxns": namespace,
}
testEnv.CreateObjectFile(objectFile, tmpl, t)
cases := []struct {
name string
arg string
goldenFile string
tmpl map[string]string
}{
{
"debug status",
"debug helmrelease test-values-inline --show-status --show-values=false",
"testdata/debug_helmrelease/status.golden.yaml",
tmpl,
},
{
"debug values",
"debug helmrelease test-values-inline --show-values --show-status=false",
"testdata/debug_helmrelease/values-inline.golden.yaml",
tmpl,
},
{
"debug values from",
"debug helmrelease test-values-from --show-values --show-status=false",
"testdata/debug_helmrelease/values-from.golden.yaml",
tmpl,
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
cmd := cmdTestCase{
args: tt.arg + " -n=" + namespace,
assert: assertGoldenTemplateFile(tt.goldenFile, tmpl),
}
cmd.runTestCmd(t)
})
}
}

@ -1,134 +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 main
import (
"context"
"errors"
"fmt"
"sort"
"strings"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/kustomize"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/yaml"
"github.com/fluxcd/flux2/v2/internal/utils"
)
var debugKustomizationCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Debug a Flux Kustomization resource",
Long: withPreviewNote(`The debug kustomization command can be used to troubleshoot failing Flux Kustomization reconciliations.
WARNING: This command will print sensitive information if Kubernetes Secrets are referenced in the Kustomization .spec.postBuild.substituteFrom field.`),
Example: ` # Print the status of a Flux Kustomization
flux debug ks podinfo --show-status
# Export the final variables used for post-build substitutions composed from referred ConfigMaps and Secrets
flux debug ks podinfo --show-vars > vars.env`,
RunE: debugKustomizationCmdRun,
Args: cobra.ExactArgs(1),
ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
}
type debugKustomizationFlags struct {
showStatus bool
showVars bool
}
var debugKustomizationArgs debugKustomizationFlags
func init() {
debugKustomizationCmd.Flags().BoolVar(&debugKustomizationArgs.showStatus, "show-status", false, "print the status of the Flux Kustomization")
debugKustomizationCmd.Flags().BoolVar(&debugKustomizationArgs.showVars, "show-vars", false, "print the final vars of the Flux Kustomization in dot env format")
debugCmd.AddCommand(debugKustomizationCmd)
}
func debugKustomizationCmdRun(cmd *cobra.Command, args []string) error {
name := args[0]
if (!debugKustomizationArgs.showStatus && !debugKustomizationArgs.showVars) ||
(debugKustomizationArgs.showStatus && debugKustomizationArgs.showVars) {
return fmt.Errorf("either --show-status or --show-vars must be set")
}
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
if err != nil {
return err
}
ks := &kustomizev1.Kustomization{}
ksName := types.NamespacedName{Namespace: *kubeconfigArgs.Namespace, Name: name}
if err := kubeClient.Get(ctx, ksName, ks); err != nil {
return err
}
if debugKustomizationArgs.showStatus {
status, err := yaml.Marshal(ks.Status)
if err != nil {
return err
}
rootCmd.Println("# Status documentation: https://fluxcd.io/flux/components/kustomize/kustomizations/#kustomization-status")
rootCmd.Print(string(status))
return nil
}
if debugKustomizationArgs.showVars {
if ks.Spec.PostBuild == nil {
return errors.New("no post build substitutions found")
}
ksObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(ks)
if err != nil {
return err
}
finalVars, err := kustomize.LoadVariables(ctx, kubeClient, unstructured.Unstructured{Object: ksObj})
if err != nil {
return err
}
if len(ks.Spec.PostBuild.Substitute) > 0 {
for k, v := range ks.Spec.PostBuild.Substitute {
// Remove new lines from the values as they are not supported.
// Replicates the controller behavior from
// https://github.com/fluxcd/pkg/blob/main/kustomize/kustomize_varsub.go
finalVars[k] = strings.ReplaceAll(v, "\n", "")
}
}
keys := make([]string, 0, len(finalVars))
for k := range finalVars {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
rootCmd.Println(k + "=" + finalVars[k])
}
}
return nil
}

@ -1,71 +0,0 @@
//go:build unit
// +build unit
/*
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 main
import (
"testing"
)
func TestDebugKustomization(t *testing.T) {
namespace := allocateNamespace("debug")
objectFile := "testdata/debug_kustomization/objects.yaml"
tmpl := map[string]string{
"fluxns": namespace,
}
testEnv.CreateObjectFile(objectFile, tmpl, t)
cases := []struct {
name string
arg string
goldenFile string
tmpl map[string]string
}{
{
"debug status",
"debug ks test --show-status --show-vars=false",
"testdata/debug_kustomization/status.golden.yaml",
tmpl,
},
{
"debug vars",
"debug ks test --show-vars --show-status=false",
"testdata/debug_kustomization/vars.golden.env",
tmpl,
},
{
"debug vars from",
"debug ks test-from --show-vars --show-status=false",
"testdata/debug_kustomization/vars-from.golden.env",
tmpl,
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
cmd := cmdTestCase{
args: tt.arg + " -n=" + namespace,
assert: assertGoldenTemplateFile(tt.goldenFile, tmpl),
}
cmd.runTestCmd(t)
})
}
}

@ -19,13 +19,13 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
) )
var deleteSourceBucketCmd = &cobra.Command{ var deleteSourceBucketCmd = &cobra.Command{
Use: "bucket [name]", Use: "bucket [name]",
Short: "Delete a Bucket source", Short: "Delete a Bucket source",
Long: "The delete source bucket command deletes the given Bucket from the cluster.", Long: withPreviewNote("The delete source bucket command deletes the given Bucket from the cluster."),
Example: ` # Delete a Bucket source Example: ` # Delete a Bucket source
flux delete source bucket podinfo`, flux delete source bucket podinfo`,
ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)), ValidArgsFunction: resourceNamesCompletionFunc(sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)),

@ -23,7 +23,6 @@ import (
oci "github.com/fluxcd/pkg/oci/client" oci "github.com/fluxcd/pkg/oci/client"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/fluxcd/flux2/v2/internal/flags" "github.com/fluxcd/flux2/v2/internal/flags"
@ -43,7 +42,6 @@ type diffArtifactFlags struct {
creds string creds string
provider flags.SourceOCIProvider provider flags.SourceOCIProvider
ignorePaths []string ignorePaths []string
insecure bool
} }
var diffArtifactArgs = newDiffArtifactArgs() var diffArtifactArgs = newDiffArtifactArgs()
@ -59,7 +57,6 @@ func init() {
diffArtifactCmd.Flags().StringVar(&diffArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format <username>[:<password>] if --provider is generic") diffArtifactCmd.Flags().StringVar(&diffArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format <username>[:<password>] if --provider is generic")
diffArtifactCmd.Flags().Var(&diffArtifactArgs.provider, "provider", sourceOCIRepositoryArgs.provider.Description()) diffArtifactCmd.Flags().Var(&diffArtifactArgs.provider, "provider", sourceOCIRepositoryArgs.provider.Description())
diffArtifactCmd.Flags().StringSliceVar(&diffArtifactArgs.ignorePaths, "ignore-paths", excludeOCI, "set paths to ignore in .gitignore format") diffArtifactCmd.Flags().StringSliceVar(&diffArtifactArgs.ignorePaths, "ignore-paths", excludeOCI, "set paths to ignore in .gitignore format")
diffArtifactCmd.Flags().BoolVar(&diffArtifactArgs.insecure, "insecure-registry", false, "allows the remote artifact to be pulled without TLS")
diffCmd.AddCommand(diffArtifactCmd) diffCmd.AddCommand(diffArtifactCmd)
} }
@ -85,13 +82,7 @@ func diffArtifactCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel() defer cancel()
opts := oci.DefaultOptions() ociClient := oci.NewClient(oci.DefaultOptions())
if diffArtifactArgs.insecure {
opts = append(opts, crane.Insecure)
}
ociClient := oci.NewClient(opts)
if diffArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && diffArtifactArgs.creds != "" { if diffArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && diffArtifactArgs.creds != "" {
logger.Actionf("logging in to registry with credentials") logger.Actionf("logging in to registry with credentials")

@ -44,12 +44,7 @@ flux diff kustomization my-app --path ./path/to/local/manifests \
# Exclude files by providing a comma separated list of entries that follow the .gitignore pattern fromat. # Exclude files by providing a comma separated list of entries that follow the .gitignore pattern fromat.
flux diff kustomization my-app --path ./path/to/local/manifests \ flux diff kustomization my-app --path ./path/to/local/manifests \
--kustomization-file ./path/to/local/my-app.yaml \ --kustomization-file ./path/to/local/my-app.yaml \
--ignore-paths "/to_ignore/**/*.yaml,ignore.yaml" --ignore-paths "/to_ignore/**/*.yaml,ignore.yaml"`,
# Run recursively on all encountered Kustomizations
flux diff kustomization my-app --path ./path/to/local/manifests \
--recursive \
--local-sources GitRepository/flux-system/my-repo=./path/to/local/git`,
ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
RunE: diffKsCmdRun, RunE: diffKsCmdRun,
} }
@ -60,8 +55,6 @@ type diffKsFlags struct {
ignorePaths []string ignorePaths []string
progressBar bool progressBar bool
strictSubst bool strictSubst bool
recursive bool
localSources map[string]string
} }
var diffKsArgs diffKsFlags var diffKsArgs diffKsFlags
@ -73,8 +66,6 @@ func init() {
diffKsCmd.Flags().StringVar(&diffKsArgs.kustomizationFile, "kustomization-file", "", "Path to the Flux Kustomization YAML file.") diffKsCmd.Flags().StringVar(&diffKsArgs.kustomizationFile, "kustomization-file", "", "Path to the Flux Kustomization YAML file.")
diffKsCmd.Flags().BoolVar(&diffKsArgs.strictSubst, "strict-substitute", false, diffKsCmd.Flags().BoolVar(&diffKsArgs.strictSubst, "strict-substitute", false,
"When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.") "When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.")
diffKsCmd.Flags().BoolVarP(&diffKsArgs.recursive, "recursive", "r", false, "Recursively diff Kustomizations")
diffKsCmd.Flags().StringToStringVar(&diffKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path")
diffCmd.AddCommand(diffKsCmd) diffCmd.AddCommand(diffKsCmd)
} }
@ -110,9 +101,6 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error {
build.WithProgressBar(), build.WithProgressBar(),
build.WithIgnore(diffKsArgs.ignorePaths), build.WithIgnore(diffKsArgs.ignorePaths),
build.WithStrictSubstitute(diffKsArgs.strictSubst), build.WithStrictSubstitute(diffKsArgs.strictSubst),
build.WithRecursive(diffKsArgs.recursive),
build.WithLocalSources(diffKsArgs.localSources),
build.WithSingleKustomization(),
) )
} else { } else {
builder, err = build.NewBuilder(name, diffKsArgs.path, builder, err = build.NewBuilder(name, diffKsArgs.path,
@ -121,9 +109,6 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error {
build.WithKustomizationFile(diffKsArgs.kustomizationFile), build.WithKustomizationFile(diffKsArgs.kustomizationFile),
build.WithIgnore(diffKsArgs.ignorePaths), build.WithIgnore(diffKsArgs.ignorePaths),
build.WithStrictSubstitute(diffKsArgs.strictSubst), build.WithStrictSubstitute(diffKsArgs.strictSubst),
build.WithRecursive(diffKsArgs.recursive),
build.WithLocalSources(diffKsArgs.localSources),
build.WithSingleKustomization(),
) )
} }
@ -153,12 +138,6 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error {
select { select {
case <-sigc: case <-sigc:
if diffKsArgs.progressBar {
err := builder.StopSpinner()
if err != nil {
return err
}
}
fmt.Println("Build cancelled... exiting.") fmt.Println("Build cancelled... exiting.")
return builder.Cancel() return builder.Cancel()
case err := <-errChan: case err := <-errChan:

@ -97,12 +97,6 @@ func TestDiffKustomization(t *testing.T) {
objectFile: "", objectFile: "",
assert: assertGoldenFile("./testdata/diff-kustomization/nothing-is-deployed.golden"), assert: assertGoldenFile("./testdata/diff-kustomization/nothing-is-deployed.golden"),
}, },
{
name: "diff with recursive",
args: "diff kustomization podinfo --path ./testdata/build-kustomization/podinfo-with-my-app --progress-bar=false --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization",
objectFile: "./testdata/diff-kustomization/my-app.yaml",
assert: assertGoldenFile("./testdata/diff-kustomization/diff-with-recursive.golden"),
},
} }
tmpl := map[string]string{ tmpl := map[string]string{

@ -447,7 +447,7 @@ var fluxKindMap = refMap{
}, },
sourcev1.GitRepositoryKind: {gvk: sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)}, sourcev1.GitRepositoryKind: {gvk: sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)},
sourcev1b2.OCIRepositoryKind: {gvk: sourcev1b2.GroupVersion.WithKind(sourcev1b2.OCIRepositoryKind)}, sourcev1b2.OCIRepositoryKind: {gvk: sourcev1b2.GroupVersion.WithKind(sourcev1b2.OCIRepositoryKind)},
sourcev1.BucketKind: {gvk: sourcev1.GroupVersion.WithKind(sourcev1.BucketKind)}, sourcev1b2.BucketKind: {gvk: sourcev1b2.GroupVersion.WithKind(sourcev1b2.BucketKind)},
sourcev1.HelmRepositoryKind: {gvk: sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)}, sourcev1.HelmRepositoryKind: {gvk: sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)},
autov1.ImageUpdateAutomationKind: {gvk: autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)}, autov1.ImageUpdateAutomationKind: {gvk: autov1.GroupVersion.WithKind(autov1.ImageUpdateAutomationKind)},
imagev1.ImageRepositoryKind: {gvk: imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)}, imagev1.ImageRepositoryKind: {gvk: imagev1.GroupVersion.WithKind(imagev1.ImageRepositoryKind)},

@ -21,13 +21,13 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
) )
var exportSourceBucketCmd = &cobra.Command{ var exportSourceBucketCmd = &cobra.Command{
Use: "bucket [name]", Use: "bucket [name]",
Short: "Export Bucket sources in YAML format", Short: "Export Bucket sources in YAML format",
Long: "The export source git command exports one or all Bucket sources in YAML format.", Long: withPreviewNote("The export source git command exports one or all Bucket sources in YAML format."),
Example: ` # Export all Bucket sources Example: ` # Export all Bucket sources
flux export source bucket --all > sources.yaml flux export source bucket --all > sources.yaml

@ -1,22 +1,6 @@
//go:build unit //go:build unit
// +build unit // +build unit
/*
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 main package main
import ( import (

@ -46,7 +46,7 @@ var getSourceAllCmd = &cobra.Command{
}, },
{ {
apiType: bucketType, apiType: bucketType,
list: &bucketListAdapter{&sourcev1.BucketList{}}, list: &bucketListAdapter{&sourcev1b2.BucketList{}},
}, },
{ {
apiType: gitRepositoryType, apiType: gitRepositoryType,

@ -25,7 +25,7 @@ import (
"golang.org/x/text/language" "golang.org/x/text/language"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/flux2/v2/internal/utils" "github.com/fluxcd/flux2/v2/internal/utils"
) )
@ -33,7 +33,7 @@ import (
var getSourceBucketCmd = &cobra.Command{ var getSourceBucketCmd = &cobra.Command{
Use: "bucket", Use: "bucket",
Short: "Get Bucket source statuses", Short: "Get Bucket source statuses",
Long: "The get sources bucket command prints the status of the Bucket sources.", Long: withPreviewNote("The get sources bucket command prints the status of the Bucket sources."),
Example: ` # List all Buckets and their status Example: ` # List all Buckets and their status
flux get sources bucket flux get sources bucket

@ -20,7 +20,6 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/spf13/cobra" "github.com/spf13/cobra"
oci "github.com/fluxcd/pkg/oci/client" oci "github.com/fluxcd/pkg/oci/client"
@ -35,7 +34,6 @@ type listArtifactFlags struct {
regexFilter string regexFilter string
creds string creds string
provider flags.SourceOCIProvider provider flags.SourceOCIProvider
insecure bool
} }
var listArtifactArgs = newListArtifactFlags() var listArtifactArgs = newListArtifactFlags()
@ -62,7 +60,6 @@ func init() {
listArtifactsCmd.Flags().StringVar(&listArtifactArgs.regexFilter, "filter-regex", "", "filter tags returned from the oci repository using regex") listArtifactsCmd.Flags().StringVar(&listArtifactArgs.regexFilter, "filter-regex", "", "filter tags returned from the oci repository using regex")
listArtifactsCmd.Flags().StringVar(&listArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format <username>[:<password>] if --provider is generic") listArtifactsCmd.Flags().StringVar(&listArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format <username>[:<password>] if --provider is generic")
listArtifactsCmd.Flags().Var(&listArtifactArgs.provider, "provider", listArtifactArgs.provider.Description()) listArtifactsCmd.Flags().Var(&listArtifactArgs.provider, "provider", listArtifactArgs.provider.Description())
listArtifactsCmd.Flags().BoolVar(&listArtifactArgs.insecure, "insecure-registry", false, "allows the remote artifacts list to be fetched without TLS")
listCmd.AddCommand(listArtifactsCmd) listCmd.AddCommand(listArtifactsCmd)
} }
@ -81,13 +78,7 @@ func listArtifactsCmdRun(cmd *cobra.Command, args []string) error {
return err return err
} }
ociOpts := oci.DefaultOptions() ociClient := oci.NewClient(oci.DefaultOptions())
if listArtifactArgs.insecure {
ociOpts = append(ociOpts, crane.Insecure)
}
ociClient := oci.NewClient(ociOpts)
if listArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && listArtifactArgs.creds != "" { if listArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && listArtifactArgs.creds != "" {
logger.Actionf("logging in to registry with credentials") logger.Actionf("logging in to registry with credentials")

@ -235,7 +235,7 @@ func parallelPodLogs(ctx context.Context, requests []rest.ResponseWrapper) error
return errors.Join(<-stdoutErrCh, <-stderrErrCh) return errors.Join(<-stdoutErrCh, <-stderrErrCh)
} }
// asyncCopy copies all data from dst to src asynchronously and returns a channel for reading an error value. // asyncCopy copies all data from from dst to src asynchronously and returns a channel for reading an error value.
// This is basically an asynchronous wrapper around `io.Copy`. The returned channel is unbuffered and always is sent // This is basically an asynchronous wrapper around `io.Copy`. The returned channel is unbuffered and always is sent
// a value (either nil or the error from `io.Copy`) as soon as `io.Copy` returns. // a value (either nil or the error from `io.Copy`) as soon as `io.Copy` returns.
// This function lets you copy from multiple sources into multiple destinations in parallel. // This function lets you copy from multiple sources into multiple destinations in parallel.

@ -429,9 +429,7 @@ func resetCmdArgs() {
tail: -1, tail: -1,
fluxNamespace: rootArgs.defaults.Namespace, fluxNamespace: rootArgs.defaults.Namespace,
} }
buildKsArgs = buildKsFlags{ buildKsArgs = buildKsFlags{}
localSources: map[string]string{},
}
checkArgs = checkFlags{} checkArgs = checkFlags{}
createArgs = createFlags{} createArgs = createFlags{}
deleteArgs = deleteFlags{} deleteArgs = deleteFlags{}
@ -453,7 +451,6 @@ func resetCmdArgs() {
rhrArgs = reconcileHelmReleaseFlags{} rhrArgs = reconcileHelmReleaseFlags{}
rksArgs = reconcileKsFlags{} rksArgs = reconcileKsFlags{}
secretGitArgs = NewSecretGitFlags() secretGitArgs = NewSecretGitFlags()
secretProxyArgs = secretProxyFlags{}
secretHelmArgs = secretHelmFlags{} secretHelmArgs = secretHelmFlags{}
secretTLSArgs = secretTLSFlags{} secretTLSArgs = secretTLSFlags{}
sourceBucketArgs = sourceBucketFlags{} sourceBucketArgs = sourceBucketFlags{}
@ -469,8 +466,6 @@ func resetCmdArgs() {
output: "yaml", output: "yaml",
} }
envsubstArgs = envsubstFlags{} envsubstArgs = envsubstFlags{}
debugHelmReleaseArgs = debugHelmReleaseFlags{}
debugKustomizationArgs = debugKustomizationFlags{}
} }
func isChangeError(err error) bool { func isChangeError(err error) bool {

@ -22,7 +22,6 @@ import (
"os" "os"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/fluxcd/flux2/v2/internal/flags" "github.com/fluxcd/flux2/v2/internal/flags"
@ -44,7 +43,6 @@ The command can read the credentials from '~/.docker/config.json' but they can a
type pullArtifactFlags struct { type pullArtifactFlags struct {
output string output string
creds string creds string
insecure bool
provider flags.SourceOCIProvider provider flags.SourceOCIProvider
} }
@ -60,7 +58,6 @@ func init() {
pullArtifactCmd.Flags().StringVarP(&pullArtifactArgs.output, "output", "o", "", "path where the artifact content should be extracted.") pullArtifactCmd.Flags().StringVarP(&pullArtifactArgs.output, "output", "o", "", "path where the artifact content should be extracted.")
pullArtifactCmd.Flags().StringVar(&pullArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format <username>[:<password>] if --provider is generic") pullArtifactCmd.Flags().StringVar(&pullArtifactArgs.creds, "creds", "", "credentials for OCI registry in the format <username>[:<password>] if --provider is generic")
pullArtifactCmd.Flags().Var(&pullArtifactArgs.provider, "provider", sourceOCIRepositoryArgs.provider.Description()) pullArtifactCmd.Flags().Var(&pullArtifactArgs.provider, "provider", sourceOCIRepositoryArgs.provider.Description())
pullArtifactCmd.Flags().BoolVar(&pullArtifactArgs.insecure, "insecure-registry", false, "allows artifacts to be pulled without TLS")
pullCmd.AddCommand(pullArtifactCmd) pullCmd.AddCommand(pullArtifactCmd)
} }
@ -86,13 +83,7 @@ func pullArtifactCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel() defer cancel()
opts := oci.DefaultOptions() ociClient := oci.NewClient(oci.DefaultOptions())
if pullArtifactArgs.insecure {
opts = append(opts, crane.Insecure)
}
ociClient := oci.NewClient(opts)
if pullArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && pullArtifactArgs.creds != "" { if pullArtifactArgs.provider.String() == sourcev1.GenericOCIProvider && pullArtifactArgs.creds != "" {
logger.Actionf("logging in to registry with credentials") logger.Actionf("logging in to registry with credentials")

@ -115,7 +115,6 @@ type pushArtifactFlags struct {
output string output string
debug bool debug bool
reproducible bool reproducible bool
insecure bool
} }
var pushArtifactArgs = newPushArtifactFlags() var pushArtifactArgs = newPushArtifactFlags()
@ -138,7 +137,6 @@ func init() {
"the format in which the artifact digest should be printed, can be 'json' or 'yaml'") "the format in which the artifact digest should be printed, can be 'json' or 'yaml'")
pushArtifactCmd.Flags().BoolVarP(&pushArtifactArgs.debug, "debug", "", false, "display logs from underlying library") pushArtifactCmd.Flags().BoolVarP(&pushArtifactArgs.debug, "debug", "", false, "display logs from underlying library")
pushArtifactCmd.Flags().BoolVar(&pushArtifactArgs.reproducible, "reproducible", false, "ensure reproducible image digests by setting the created timestamp to '1970-01-01T00:00:00Z'") pushArtifactCmd.Flags().BoolVar(&pushArtifactArgs.reproducible, "reproducible", false, "ensure reproducible image digests by setting the created timestamp to '1970-01-01T00:00:00Z'")
pushArtifactCmd.Flags().BoolVar(&pushArtifactArgs.insecure, "insecure-registry", false, "allows artifacts to be pushed without TLS")
pushCmd.AddCommand(pushArtifactCmd) pushCmd.AddCommand(pushArtifactCmd)
} }
@ -268,10 +266,6 @@ func pushArtifactCmdRun(cmd *cobra.Command, args []string) error {
logger.Actionf("pushing artifact to %s", url) logger.Actionf("pushing artifact to %s", url)
} }
if pushArtifactArgs.insecure {
opts = append(opts, crane.Insecure)
}
ociClient := client.NewClient(opts) ociClient := client.NewClient(opts)
digestURL, err := ociClient.Push(ctx, url, path, digestURL, err := ociClient.Push(ctx, url, path,
client.WithPushMetadata(meta), client.WithPushMetadata(meta),

@ -32,7 +32,7 @@ var reconcileHrCmd = &cobra.Command{
Aliases: []string{"hr"}, Aliases: []string{"hr"},
Short: "Reconcile a HelmRelease resource", Short: "Reconcile a HelmRelease resource",
Long: ` Long: `
The reconcile helmrelease command triggers a reconciliation of a HelmRelease resource and waits for it to finish.`, The reconcile kustomization command triggers a reconciliation of a HelmRelease resource and waits for it to finish.`,
Example: ` # Trigger a HelmRelease apply outside of the reconciliation interval Example: ` # Trigger a HelmRelease apply outside of the reconciliation interval
flux reconcile hr podinfo flux reconcile hr podinfo

@ -76,10 +76,10 @@ func (obj kustomizationAdapter) getSource() (reconcileSource, types.NamespacedNa
apiType: gitRepositoryType, apiType: gitRepositoryType,
object: gitRepositoryAdapter{&sourcev1.GitRepository{}}, object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
} }
case sourcev1.BucketKind: case sourcev1b2.BucketKind:
cmd = reconcileCommand{ cmd = reconcileCommand{
apiType: bucketType, apiType: bucketType,
object: bucketAdapter{&sourcev1.Bucket{}}, object: bucketAdapter{&sourcev1b2.Bucket{}},
} }
} }

@ -21,7 +21,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
) )
var reconcileSourceBucketCmd = &cobra.Command{ var reconcileSourceBucketCmd = &cobra.Command{

@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2"
) )
var reconcileSourceHelmChartCmd = &cobra.Command{ var reconcileSourceHelmChartCmd = &cobra.Command{
@ -71,10 +72,10 @@ func (obj helmChartAdapter) getSource() (reconcileSource, types.NamespacedName)
apiType: gitRepositoryType, apiType: gitRepositoryType,
object: gitRepositoryAdapter{&sourcev1.GitRepository{}}, object: gitRepositoryAdapter{&sourcev1.GitRepository{}},
} }
case sourcev1.BucketKind: case sourcev1b2.BucketKind:
cmd = reconcileCommand{ cmd = reconcileCommand{
apiType: bucketType, apiType: bucketType,
object: bucketAdapter{&sourcev1.Bucket{}}, object: bucketAdapter{&sourcev1b2.Bucket{}},
} }
} }

@ -133,7 +133,7 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error {
// If the args slice is empty, it patches all resumable objects in the given namespace. // If the args slice is empty, it patches all resumable objects in the given namespace.
func (resume *resumeCommand) getPatchedResumables(ctx context.Context, args []string) ([]resumable, error) { func (resume *resumeCommand) getPatchedResumables(ctx context.Context, args []string) ([]resumable, error) {
if len(args) < 1 { if len(args) < 1 {
objs, err := resume.patch(ctx, args, []client.ListOption{ objs, err := resume.patch(ctx, []client.ListOption{
client.InNamespace(resume.namespace), client.InNamespace(resume.namespace),
}) })
if err != nil { if err != nil {
@ -151,7 +151,7 @@ func (resume *resumeCommand) getPatchedResumables(ctx context.Context, args []st
} }
processed[arg] = struct{}{} processed[arg] = struct{}{}
objs, err := resume.patch(ctx, args, []client.ListOption{ objs, err := resume.patch(ctx, []client.ListOption{
client.InNamespace(resume.namespace), client.InNamespace(resume.namespace),
client.MatchingFields{ client.MatchingFields{
"metadata.name": arg, "metadata.name": arg,
@ -169,17 +169,13 @@ func (resume *resumeCommand) getPatchedResumables(ctx context.Context, args []st
// Patches resumable objects by setting their status to unsuspended. // Patches resumable objects by setting their status to unsuspended.
// Returns a slice of resumables that have been patched and any error encountered during patching. // Returns a slice of resumables that have been patched and any error encountered during patching.
func (resume resumeCommand) patch(ctx context.Context, args []string, listOpts []client.ListOption) ([]resumable, error) { func (resume resumeCommand) patch(ctx context.Context, listOpts []client.ListOption) ([]resumable, error) {
if err := resume.client.List(ctx, resume.list.asClientList(), listOpts...); err != nil { if err := resume.client.List(ctx, resume.list.asClientList(), listOpts...); err != nil {
return nil, err return nil, err
} }
if resume.list.len() == 0 { if resume.list.len() == 0 {
if len(args) < 1 {
logger.Failuref("no %s objects found in %s namespace", resume.kind, resume.namespace) logger.Failuref("no %s objects found in %s namespace", resume.kind, resume.namespace)
} else {
logger.Failuref("%s object '%s' not found in %s namespace", resume.kind, args[0], resume.namespace)
}
return nil, nil return nil, nil
} }

@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
) )
var resumeSourceBucketCmd = &cobra.Command{ var resumeSourceBucketCmd = &cobra.Command{

@ -61,16 +61,16 @@ func (a ociRepositoryListAdapter) len() int {
return len(a.OCIRepositoryList.Items) return len(a.OCIRepositoryList.Items)
} }
// sourcev1.Bucket // sourcev1b2.Bucket
var bucketType = apiType{ var bucketType = apiType{
kind: sourcev1.BucketKind, kind: sourcev1b2.BucketKind,
humanKind: "source bucket", humanKind: "source bucket",
groupVersion: sourcev1.GroupVersion, groupVersion: sourcev1b2.GroupVersion,
} }
type bucketAdapter struct { type bucketAdapter struct {
*sourcev1.Bucket *sourcev1b2.Bucket
} }
func (a bucketAdapter) asClientObject() client.Object { func (a bucketAdapter) asClientObject() client.Object {
@ -81,10 +81,10 @@ func (a bucketAdapter) deepCopyClientObject() client.Object {
return a.Bucket.DeepCopy() return a.Bucket.DeepCopy()
} }
// sourcev1.BucketList // sourcev1b2.BucketList
type bucketListAdapter struct { type bucketListAdapter struct {
*sourcev1.BucketList *sourcev1b2.BucketList
} }
func (a bucketListAdapter) asClientList() client.ObjectList { func (a bucketListAdapter) asClientList() client.ObjectList {

@ -97,9 +97,9 @@ func runStatsCmd(cmd *cobra.Command, args []string) error {
Group: sourcev1.GroupVersion.Group, Group: sourcev1.GroupVersion.Group,
}, },
{ {
Kind: sourcev1.BucketKind, Kind: sourcev1b2.BucketKind,
Version: sourcev1.GroupVersion.Version, Version: sourcev1b2.GroupVersion.Version,
Group: sourcev1.GroupVersion.Group, Group: sourcev1b2.GroupVersion.Group,
}, },
{ {
Kind: kustomizev1.KustomizationKind, Kind: kustomizev1.KustomizationKind,

@ -19,7 +19,7 @@ package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
sourcev1 "github.com/fluxcd/source-controller/api/v1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
) )
var suspendSourceBucketCmd = &cobra.Command{ var suspendSourceBucketCmd = &cobra.Command{

@ -1,6 +0,0 @@
apiVersion: v1
data:
var: test
kind: ConfigMap
metadata:
name: my-app

@ -1,29 +0,0 @@
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: podinfo
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: my-app
namespace: default
spec:
force: true
interval: 5m0s
path: ./my-app
prune: true
sourceRef:
kind: GitRepository
name: podinfo
targetNamespace: default
---
apiVersion: v1
data:
var: test
kind: ConfigMap
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: my-app
kustomize.toolkit.fluxcd.io/namespace: default
name: my-app
namespace: default
---

@ -1,4 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./my-app.yaml

@ -1,14 +0,0 @@
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
spec:
interval: 5m0s
path: ./my-app
force: true
prune: true
sourceRef:
kind: GitRepository
name: podinfo
targetNamespace: default

@ -1,3 +1,3 @@
► checking prerequisites ► checking prerequisites
✔ Kubernetes {{ .serverVersion }} >=1.30.0-0 ✔ Kubernetes {{ .serverVersion }} >=1.28.0-0
✔ prerequisites checks passed ✔ prerequisites checks passed

@ -1,39 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: appinfo
namespace: my-namespace
stringData:
githubAppBaseURL: www.example.com/api/v3
githubAppID: "1"
githubAppInstallationID: "2"
githubAppPrivateKey: |-
-----BEGIN RSA PRIVATE KEY-----
YcE2CgWILk+uiVNseHnOU2frG7k2RJZtdDo8GNI6pQWFlwU/NsQoJBrtEDyYVkap
PLv7VoJ2pr6l5IEwH++naL2McuCcwhW/CeaVb/IuSCFFMwb40zRrlqp6IB5VkMhm
zSde2KD/ilB1YUhaAv0qaBHLTGBvVgxut1eIyvqVC+ArWoqJ7rQTst+Arp3UAiIm
LsXqL2iZvVvCH0FiDwBIfxAMhl6fnPzuQsZBiRLPdD67jubPseN1P5JBRw3WTton
Fa2RLLByuyge7bWh2o1hjEx2w2ZpIhosQRyDs1sPXP5TI92RzOcx1CZaTZ6V5E+T
MROFeZmxBHYon1Y4Rw+jCSXovNyHbMBpMI67nwIDAQABAoIBAC4UrkusU8r7ilFu
w1LWDm09+8WSIk9KgYMoBceAqH+b9DU7hrMFrKkO/cr0Mijr1somv6B3MG83WUcB
FkhEBrwXKnh499iiO/SUo+7kaq0WLQ7mQ2Q9wpMmkkjnr0tgydAno/uNNITSaqmk
YcE2CgWILk+uiVNseHnOU2frG7k2RJZtdDo8GNI6pQWFlwU/NsQoJBrtEDyYVkap
Fa2RLLByuyge7bWh2o1hjEx2w2ZpIhosQRyDs1sPXP5TI92RzOcx1CZaTZ6V5E+T
zSde2KD/ilB1YUhaAv0qaBHLTGBvVgxut1eIyvqVC+ArWoqJ7rQTst+Arp3UAiIm
ihlXNkECgYEA3abZJZuVarHPlAqRYkprs0O+DrP6sPlmVQp+nq8y3Qg00U+N7AuP
Y1riLo3gWq7LajkGTygWLmru2mhWsETxt+R4BtnREUq8kDEoCfEwPlHfqfphvBZL
j5eL60QTKAqSOVqMgIzqJyxa5FGgPGqWpLDLopyVeoyNdZwcuCQzFgkCgYEA25dm
PLv7VoJ2pr6l5IEwH++naL2McuCcwhW/CeaVb/IuSCFFMwb40zRrlqp6IB5VkMhm
MkvaCGIAH+lfJrtTSujFaOIGFy+0ZwP+LNqHUKih14y8Qv9dEP0kaXkAD3fO3Y97
Nj+Q2c06JpojgBKBMwVvT7M53w9KEoNKpoKBbmcCgYBelHyiRJJsdbVKyXuiAnmU
g/qMkZYOgE1/SjwfgEjm8kJ/cj/wEjq8PaK4FMhAScf46p5blpJoei6zucQL8U9n
lbD102oXw9lUefVI0McyQIN9J58ewDC79AG7gU/fTSt6F75OeFLOJmoedQo33Y+s
dNhf6gsKwQD3x4aluKSn6QKBgD8HbvBAKV6P4vIiFzS0QvWtpeKam2EDHI+h+WsP
nD77QoG/EPvpjJS9/KWgZRPz6U+0M5V0y73MZVzkbbVT/uwfgF2G91lXAr4Kfuh5
w1LWDm09+8WSIk9KgYMoBceAqH+b9DU7hrMFrKkO/cr0Mijr1somv6B3MG83WUcB
qCEDAoGACl8ClvMJR2uNWdaWnCz9tyPdHYgEusJ0OIP+WUY2ToYQWSlA0zNpc21Y
lbD102oXw9lUefVI0McyQIN9J58ewDC79AG7gU/fTSt6F75OeFLOJmoedQo33Y+s
bUytJtOhHbLRNxwgalhjBUNWICrDktqJmumNOEOOPBqVz7RGwUg=
-----END RSA PRIVATE KEY-----

@ -1,38 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: appinfo
namespace: my-namespace
stringData:
githubAppID: "1"
githubAppInstallationID: "2"
githubAppPrivateKey: |-
-----BEGIN RSA PRIVATE KEY-----
YcE2CgWILk+uiVNseHnOU2frG7k2RJZtdDo8GNI6pQWFlwU/NsQoJBrtEDyYVkap
PLv7VoJ2pr6l5IEwH++naL2McuCcwhW/CeaVb/IuSCFFMwb40zRrlqp6IB5VkMhm
zSde2KD/ilB1YUhaAv0qaBHLTGBvVgxut1eIyvqVC+ArWoqJ7rQTst+Arp3UAiIm
LsXqL2iZvVvCH0FiDwBIfxAMhl6fnPzuQsZBiRLPdD67jubPseN1P5JBRw3WTton
Fa2RLLByuyge7bWh2o1hjEx2w2ZpIhosQRyDs1sPXP5TI92RzOcx1CZaTZ6V5E+T
MROFeZmxBHYon1Y4Rw+jCSXovNyHbMBpMI67nwIDAQABAoIBAC4UrkusU8r7ilFu
w1LWDm09+8WSIk9KgYMoBceAqH+b9DU7hrMFrKkO/cr0Mijr1somv6B3MG83WUcB
FkhEBrwXKnh499iiO/SUo+7kaq0WLQ7mQ2Q9wpMmkkjnr0tgydAno/uNNITSaqmk
YcE2CgWILk+uiVNseHnOU2frG7k2RJZtdDo8GNI6pQWFlwU/NsQoJBrtEDyYVkap
Fa2RLLByuyge7bWh2o1hjEx2w2ZpIhosQRyDs1sPXP5TI92RzOcx1CZaTZ6V5E+T
zSde2KD/ilB1YUhaAv0qaBHLTGBvVgxut1eIyvqVC+ArWoqJ7rQTst+Arp3UAiIm
ihlXNkECgYEA3abZJZuVarHPlAqRYkprs0O+DrP6sPlmVQp+nq8y3Qg00U+N7AuP
Y1riLo3gWq7LajkGTygWLmru2mhWsETxt+R4BtnREUq8kDEoCfEwPlHfqfphvBZL
j5eL60QTKAqSOVqMgIzqJyxa5FGgPGqWpLDLopyVeoyNdZwcuCQzFgkCgYEA25dm
PLv7VoJ2pr6l5IEwH++naL2McuCcwhW/CeaVb/IuSCFFMwb40zRrlqp6IB5VkMhm
MkvaCGIAH+lfJrtTSujFaOIGFy+0ZwP+LNqHUKih14y8Qv9dEP0kaXkAD3fO3Y97
Nj+Q2c06JpojgBKBMwVvT7M53w9KEoNKpoKBbmcCgYBelHyiRJJsdbVKyXuiAnmU
g/qMkZYOgE1/SjwfgEjm8kJ/cj/wEjq8PaK4FMhAScf46p5blpJoei6zucQL8U9n
lbD102oXw9lUefVI0McyQIN9J58ewDC79AG7gU/fTSt6F75OeFLOJmoedQo33Y+s
dNhf6gsKwQD3x4aluKSn6QKBgD8HbvBAKV6P4vIiFzS0QvWtpeKam2EDHI+h+WsP
nD77QoG/EPvpjJS9/KWgZRPz6U+0M5V0y73MZVzkbbVT/uwfgF2G91lXAr4Kfuh5
w1LWDm09+8WSIk9KgYMoBceAqH+b9DU7hrMFrKkO/cr0Mijr1somv6B3MG83WUcB
qCEDAoGACl8ClvMJR2uNWdaWnCz9tyPdHYgEusJ0OIP+WUY2ToYQWSlA0zNpc21Y
lbD102oXw9lUefVI0McyQIN9J58ewDC79AG7gU/fTSt6F75OeFLOJmoedQo33Y+s
bUytJtOhHbLRNxwgalhjBUNWICrDktqJmumNOEOOPBqVz7RGwUg=
-----END RSA PRIVATE KEY-----

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
YcE2CgWILk+uiVNseHnOU2frG7k2RJZtdDo8GNI6pQWFlwU/NsQoJBrtEDyYVkap
PLv7VoJ2pr6l5IEwH++naL2McuCcwhW/CeaVb/IuSCFFMwb40zRrlqp6IB5VkMhm
zSde2KD/ilB1YUhaAv0qaBHLTGBvVgxut1eIyvqVC+ArWoqJ7rQTst+Arp3UAiIm
LsXqL2iZvVvCH0FiDwBIfxAMhl6fnPzuQsZBiRLPdD67jubPseN1P5JBRw3WTton
Fa2RLLByuyge7bWh2o1hjEx2w2ZpIhosQRyDs1sPXP5TI92RzOcx1CZaTZ6V5E+T
MROFeZmxBHYon1Y4Rw+jCSXovNyHbMBpMI67nwIDAQABAoIBAC4UrkusU8r7ilFu
w1LWDm09+8WSIk9KgYMoBceAqH+b9DU7hrMFrKkO/cr0Mijr1somv6B3MG83WUcB
FkhEBrwXKnh499iiO/SUo+7kaq0WLQ7mQ2Q9wpMmkkjnr0tgydAno/uNNITSaqmk
YcE2CgWILk+uiVNseHnOU2frG7k2RJZtdDo8GNI6pQWFlwU/NsQoJBrtEDyYVkap
Fa2RLLByuyge7bWh2o1hjEx2w2ZpIhosQRyDs1sPXP5TI92RzOcx1CZaTZ6V5E+T
zSde2KD/ilB1YUhaAv0qaBHLTGBvVgxut1eIyvqVC+ArWoqJ7rQTst+Arp3UAiIm
ihlXNkECgYEA3abZJZuVarHPlAqRYkprs0O+DrP6sPlmVQp+nq8y3Qg00U+N7AuP
Y1riLo3gWq7LajkGTygWLmru2mhWsETxt+R4BtnREUq8kDEoCfEwPlHfqfphvBZL
j5eL60QTKAqSOVqMgIzqJyxa5FGgPGqWpLDLopyVeoyNdZwcuCQzFgkCgYEA25dm
PLv7VoJ2pr6l5IEwH++naL2McuCcwhW/CeaVb/IuSCFFMwb40zRrlqp6IB5VkMhm
MkvaCGIAH+lfJrtTSujFaOIGFy+0ZwP+LNqHUKih14y8Qv9dEP0kaXkAD3fO3Y97
Nj+Q2c06JpojgBKBMwVvT7M53w9KEoNKpoKBbmcCgYBelHyiRJJsdbVKyXuiAnmU
g/qMkZYOgE1/SjwfgEjm8kJ/cj/wEjq8PaK4FMhAScf46p5blpJoei6zucQL8U9n
lbD102oXw9lUefVI0McyQIN9J58ewDC79AG7gU/fTSt6F75OeFLOJmoedQo33Y+s
dNhf6gsKwQD3x4aluKSn6QKBgD8HbvBAKV6P4vIiFzS0QvWtpeKam2EDHI+h+WsP
nD77QoG/EPvpjJS9/KWgZRPz6U+0M5V0y73MZVzkbbVT/uwfgF2G91lXAr4Kfuh5
w1LWDm09+8WSIk9KgYMoBceAqH+b9DU7hrMFrKkO/cr0Mijr1somv6B3MG83WUcB
qCEDAoGACl8ClvMJR2uNWdaWnCz9tyPdHYgEusJ0OIP+WUY2ToYQWSlA0zNpc21Y
lbD102oXw9lUefVI0McyQIN9J58ewDC79AG7gU/fTSt6F75OeFLOJmoedQo33Y+s
bUytJtOhHbLRNxwgalhjBUNWICrDktqJmumNOEOOPBqVz7RGwUg=
-----END RSA PRIVATE KEY-----

@ -1,11 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: proxy-secret
namespace: my-namespace
stringData:
address: https://my-proxy.com
password: my-password
username: my-username

@ -0,0 +1,107 @@
Flag --cert-file has been deprecated, please use --tls-crt-file instead
Flag --key-file has been deprecated, please use --tls-key-file instead
Flag --ca-file has been deprecated, please use --ca-crt-file instead
---
apiVersion: v1
kind: Secret
metadata:
name: certs
namespace: my-namespace
stringData:
caFile: |
-----BEGIN CERTIFICATE-----
MIIBhzCCAS2gAwIBAgIUdsAtiX3gN0uk7ddxASWYE/tdv0wwCgYIKoZIzj0EAwIw
GTEXMBUGA1UEAxMOZXhhbXBsZS5jb20gQ0EwHhcNMjAwNDE3MDgxODAwWhcNMjUw
NDE2MDgxODAwWjAZMRcwFQYDVQQDEw5leGFtcGxlLmNvbSBDQTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABK7h/5D8bV93MmEdhu02JsS6ugB8s6PzRl3PV4xs3Sbr
RNkkM59+x3b0iWx/i76qPYpNLoiVUVXQmA9Y+4DbMxijUzBRMA4GA1UdDwEB/wQE
AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQGyUiU1QEZiMAqjsnIYTwZ
4yp5wzAPBgNVHREECDAGhwR/AAABMAoGCCqGSM49BAMCA0gAMEUCIQDzdtvKdE8O
1+WRTZ9MuSiFYcrEz7Zne7VXouDEKqKEigIgM4WlbDeuNCKbqhqj+xZV0pa3rweb
OD8EjjCMY69RMO0=
-----END CERTIFICATE-----
certFile: |
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIUT84jeO/ncOrqI+FY05Fzbg8Ed7MwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTA4MDgxNDQyMzVaFw0yMjA4
MDgxNDQyMzVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQDn/rPsZ74oypiwCzLlx57zplTiCi/WLSF+MmLGuTvM
EQnV+OND2zFgvDIV/vFs3brkd6rLVI4NcdgSj4YKULCMwwOl45hQPdCTEPJvUhCm
M+FuQ0czmEEJSjZtdLFz1B7QB/JemNnbfigxM9mlg58AlBhVJqn8q64wd/kC/W/K
JTLJuBiVf12ZiPoPfO4WSxAqD3opZ8gdbmK0KYQAhKjEto6ZrYGisfwU1gt3l8M7
sCJSpEkOkpuQgJ8D+xzJS36VXBJQMMP9nAPps+x/rGFplsPMsXEFFiwvR1+FJZwz
lg2sJ91bLGZQ7vn74MfsGrxpiJwllRThJyT7C9V0sjb5trT2lEqZlP2dRSJYt7aJ
1crEcdGSl6RIKgxSV6Hk8dh/ZaTjrTwaKxVkPo2IeEXy5xrR7DyonOQ6Yes0KOCm
JB5yHkFlIVEnLm/HZXEtm3bPHsFgTZuInyBCOMXpUESuVZIw8YK+Vd6AExGPPwZ4
n5I/sCDxWII9owIj3LeLzdUG6JoroahhGmo8rgpbJpPnS+VgryQ/raUQjqDzDCuE
9vKXKBlSUqK6H9A+NMc0mme7M8/GX7T7ewFGUB/xsdrcO4yXjqHnAe0yLf8epDjC
hh76bYqwwinVrmfcNcRxFVJZW2z0gGdgkOkOLaVVb9ggPV2SNAHbN4A+St/iRYR5
awIDAQABo1MwUTAdBgNVHQ4EFgQUzMaCqVM30EZFfTeNUIJ5fNPAhaQwHwYDVR0j
BBgwFoAUzMaCqVM30EZFfTeNUIJ5fNPAhaQwDwYDVR0TAQH/BAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAgEAVmk1rXtVkYR1Vs2Va/xrUaGXlFznhPU/Fft44kiEkkLp
mLVelWyAqvXYioqssZwuZnTjGz0DQPqzJjqwuGy4CHwPLmhCtfHplrbWo8a0ivYC
cL20KfZsG941siUh7LGBjTsq6mWBf2ytlFmg/fg93SgmqcEUAUcdps0JpZD8lgWB
ZMstfr6E3jaEus3OsvDD6hJNYZ5clJ5+ynLoWZ99A9JC0U46hmIZpRjbdSvasKpD
XrXTdpzyL/Do3znXE/yfoHv4//Rj2CpPHJLYRCIzvuf1mo1fWd53FjHvrbUvaHFz
CGuZROd4dC4Rx5nZw2ogIYvJ8m6HpIDkL3pBNSQJtIsvAYEQcotJoa5D/e9fu2Wr
+og37oCY4OXzViEBQvyxKD4cajNco1fgGKEaFROADwr3JceGI7Anq5W+xdUvAGNM
QuGeCueqNyrJ0CbQ1zEhwgpk/VYfB0u9m0bjMellRlKMdojby+FDCJtAJesx9no4
SQXyx+aNHhj3qReysjGNwZvBk1IHL04HAT+ogNiYhTl1J/YON4MB5UN6Y2PxP6uG
KvJGPigx4fAwfR/d78o5ngwoH9m+8FUg8+qllJ8XgIbl/VXKTk3G4ceOm4eBmrel
DwWuBhELSjtXWPWhMlkiebgejDbAear53Lia2Cc43zx/KuhMHBTlKY/vY4F2YiI=
-----END CERTIFICATE-----
keyFile: |
-----BEGIN PRIVATE KEY-----
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDn/rPsZ74oypiw
CzLlx57zplTiCi/WLSF+MmLGuTvMEQnV+OND2zFgvDIV/vFs3brkd6rLVI4NcdgS
j4YKULCMwwOl45hQPdCTEPJvUhCmM+FuQ0czmEEJSjZtdLFz1B7QB/JemNnbfigx
M9mlg58AlBhVJqn8q64wd/kC/W/KJTLJuBiVf12ZiPoPfO4WSxAqD3opZ8gdbmK0
KYQAhKjEto6ZrYGisfwU1gt3l8M7sCJSpEkOkpuQgJ8D+xzJS36VXBJQMMP9nAPp
s+x/rGFplsPMsXEFFiwvR1+FJZwzlg2sJ91bLGZQ7vn74MfsGrxpiJwllRThJyT7
C9V0sjb5trT2lEqZlP2dRSJYt7aJ1crEcdGSl6RIKgxSV6Hk8dh/ZaTjrTwaKxVk
Po2IeEXy5xrR7DyonOQ6Yes0KOCmJB5yHkFlIVEnLm/HZXEtm3bPHsFgTZuInyBC
OMXpUESuVZIw8YK+Vd6AExGPPwZ4n5I/sCDxWII9owIj3LeLzdUG6JoroahhGmo8
rgpbJpPnS+VgryQ/raUQjqDzDCuE9vKXKBlSUqK6H9A+NMc0mme7M8/GX7T7ewFG
UB/xsdrcO4yXjqHnAe0yLf8epDjChh76bYqwwinVrmfcNcRxFVJZW2z0gGdgkOkO
LaVVb9ggPV2SNAHbN4A+St/iRYR5awIDAQABAoICAQCTxuixQ/wbW8IbEWcgeyHD
LkaPndGO6jyVeF73GvL+MDRFuj558NvpNLfqzvTWVf9AnQGMd5Xs9oGegRHu7Csp
3ucp+moBYv7DT14+jtXQKOgGJpDqSqfS1RUKb/TBRXNDLGy02UScziWoAdE33zmf
UraVNwW8z1crxKA3yVw2Na++UqhGQlVLAbfXucqnJLVtNWKpkVQlezUgcfmFovsm
Iut+9MjI6/sZAqdXTLKuCKo0XjWzNKwnRecE0CYsCwzc80MvFYEiwQi1C0kwoouC
iOi8MKM/jDok+5/a3nQ7X+/ho5sbApNCJpfSXAK9YOJ3ju93+RjNuvORfp4/sW3W
OGXw6X30Ym7WS/7oYuwEILyqdyNOvKU7a+17d/W/YA60NOdA4iJI3aTfYFMD3l14
Da+D/wkTlEN3Ye7GN21A9AsZwWWiT9G5FOxWWVv7nTPG+Ix5ewehQWt/3DxhSizR
inMBizL5xpwx9LRWHnXX277lChYmPFAAMXINl1hnX6s0EY9pSDHN0IddibJkNKBD
m1CN37rqxoXQz4zoAyJGfQVkakqe16ayqI9yuQwO6AUkZcD5DYQdz9QYOTnYrQc6
6haC3D0Fmqg1s4v+6gpxZA/qTri0gVl/v/NN4Mk2/qWtK33imOedgD+5LXhZdBgJ
Mqn53AErG/AT622jvSb5UQKCAQEA/DTGLh0Ct97PCm+c+PxRFyieaHNJLWENKyxp
HoWGHfp2Bvt2Vphoi7GpRCM/yta4vCZgZmeWTQ0yBg6iPVPRA6Ho5hqh9OkUYVoh
prL3JsIU20jTutYjo2aefO4qXnJfkkXxNO2FElUHDTwtWdlGJQKvlUJwTv6xO19v
bQQkhZSpri6gIpi5Nkm2SGEtDofRJ+F6ThbQibEatL6DR00dh39MYQz+tZP5olzn
kX5bHEBWB7gy+YxTGF8FdlCSQTBBtNSKsAv3Cxj4qEHm+fu09vnH6fOZKenT2nXD
5QE/RpgQzLV1TumCjqLzqwp7bbzH+4mjsXpF3KHBZwnhMnDIRwKCAQEA63wYzjBy
no0GBBz0hOWrOwQ/AjUHfi47o3Xvl4RBjZclM171HKH7oMCnQvVKTNq8jvakCZjc
UI6i+H4R6aokiFS2xGbC2H3ZlSMFNwhb2xUs/C4Nr7JSOWZBtDy5QBspUsp26f7m
9VNVRzCmnxWV9be/1TxHDzDhslNlL5TMejbMorWnrtNG41KWwGtwvv2gApr3894j
eJNOh0WGfsMkXUM6+4v4WcCGrdV8Cr6Nvu96ZZe2PWu2dANtAfnxqogXXCoFE6r1
vie7hFSfJ2QR/vEbanED4pYGTtGYP1oseScx0u0hLhGLGccVBUNZlRbox4rIOELI
v9MLuiOL4YX7vQKCAQAGzMl3HtMe8AP3DRFXaT4qeK7ktA8KCS7YtibTatg14LXj
9E25gfx3n7+nlae3qVhrwkEhIbPcuflaTnSzYJonFet4oMkzGEGzakG0A+lEA0Ga
s/j5daKaWj71sVo1F7JZ+EbLnYfT+bTp93BllsUcZFkllhf/GUDgD++qKc1uSJbW
mm044ZNE0nH2u6ACX0kVYS/yAQ14WO0WaHiTqJGeQKFnkHkhni7B4O1hb923AkkP
hjjhn5Xx90Xnbb6zwUBURtLCcmAjzXWO29AFd3Lmoc9xEF9V0PckUb6JYyI4ngr9
6fqSuRsLC3u0ZeD0EX322zwtodVWYIodZBfNS1srAoIBAQCjTUPGeUKDQTjS0WGg
Z8T/AErRtQSlNFqXWMn2QPlUv2RE460HVi2xpOhZPtFvyqDIY7IOFbtzAfdya7rw
V9VN1bGJMdodV+jzy31qVJmerGit2SIUnYz30TnvS80L78oQZ+dfDi4MIuYYoFxs
JgQAipS1wz9kAXoCuGKLRJ0og6gVjfPjARE/w55XgiqFyEyWgfFBZOMkUsM6e7Rx
Y9Jr+puEpeRsGV9MXafPq6WQq3It0a/HmFLG0TlfDX3RzN6mQ12R7hTM8bDQa/6S
yorQSVPB1O3kzDVDo4X5KQd+XPfoVhmUYQYdsjmZlMMi6Og0uMFwgp/Epw6S3uO6
WbfhAoIBAQCOp4iIc87GyxWL8u6HrJaqmFlqkfou0hI+y9h6FfzsBYU6y3+gRYdF
wr2S9EUAb80kEQ1v0pt9417NOGc1pmYjKCZmDZ7qeGCGk2PR0U59+xJetXBWWhbq
5JxcwdRYoHyrmC/LINxzzqYOQbQevbW0zcEskeKfJsOtj9WJt6U9B1YZbE8pu2QV
xjvb+YekD2R+n/umV6eiaGfDau+EWudYVTqY0mR7y9hTiFR/KnqSsy2BUjljpacS
XBQO4ig7vY8+1+L3w2xpTN95/rXAvB4BbO/DLea9ArikePoSJ+bVTj0YwrKBghep
kOvbvVANrpsunlSAcpXm1qkV+G+xPnyJ
-----END PRIVATE KEY-----

@ -1,12 +0,0 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: podinfo
namespace: flux-system
spec:
interval: 1m0s
provider: azure
ref:
branch: test
url: https://dev.azure.com/foo/bar/_git/podinfo

@ -1,12 +0,0 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: podinfo
namespace: flux-system
spec:
interval: 1m0s
provider: generic
ref:
branch: test
url: https://github.com/stefanprodan/podinfo

@ -1,14 +0,0 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: podinfo
namespace: flux-system
spec:
interval: 1m0s
provider: github
ref:
branch: test
secretRef:
name: appinfo
url: https://github.com/stefanprodan/podinfo

@ -1,68 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .fluxns }}
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: test-values-inline
namespace: {{ .fluxns }}
spec:
chartRef:
kind: OCIRepository
name: podinfo
interval: 5m0s
values:
image:
repository: stefanprodan/podinfo
tag: 5.0.0
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: test-values-from
namespace: {{ .fluxns }}
spec:
chartRef:
kind: OCIRepository
name: podinfo
interval: 5m0s
values:
image:
repository: stefanprodan/podinfo
tag: 5.0.0
valuesFrom:
- kind: ConfigMap
name: test
- kind: Secret
name: test
valuesKey: secrets.yaml
- kind: Secret
name: test
valuesKey: flatValue
targetPath: aFlatValue
- kind: ConfigMap
name: none
optional: true
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test
namespace: {{ .fluxns }}
data:
values.yaml: |
cm: "test"
override: "cm"
---
apiVersion: v1
kind: Secret
metadata:
name: test
namespace: {{ .fluxns }}
stringData:
secrets.yaml: |
secret: "test"
override: "secret"
flatValue: some-flat-value

@ -1,2 +0,0 @@
# Status documentation: https://fluxcd.io/flux/components/helm/helmreleases/#helmrelease-status
observedGeneration: -1

@ -1,7 +0,0 @@
aFlatValue: some-flat-value
cm: test
image:
repository: stefanprodan/podinfo
tag: 5.0.0
override: secret
secret: test

@ -1,3 +0,0 @@
image:
repository: stefanprodan/podinfo
tag: 5.0.0

@ -1,63 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .fluxns }}
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: test
namespace: {{ .fluxns }}
spec:
sourceRef:
kind: GitRepository
name: test
interval: 1m
path: "./"
prune: true
postBuild:
substitute:
TEST_OVERRIDE: "in-line"
TEST_INLINE: "in-line"
substituteFrom:
- kind: ConfigMap
name: test
- kind: Secret
name: test
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: test-from
namespace: {{ .fluxns }}
spec:
sourceRef:
kind: GitRepository
name: test
interval: 1m
path: "./"
prune: true
postBuild:
substituteFrom:
- kind: ConfigMap
name: test
- kind: Secret
name: test
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test
namespace: {{ .fluxns }}
data:
TEST_OVERRIDE: "cm"
TEST_CM: "cm"
---
apiVersion: v1
kind: Secret
metadata:
name: test
namespace: {{ .fluxns }}
stringData:
TEST_OVERRIDE: "secret"
TEST_SECRET: "secret"

@ -1,2 +0,0 @@
# Status documentation: https://fluxcd.io/flux/components/kustomize/kustomizations/#kustomization-status
observedGeneration: -1

@ -1,3 +0,0 @@
TEST_CM=cm
TEST_OVERRIDE=secret
TEST_SECRET=secret

@ -1,4 +0,0 @@
TEST_CM=cm
TEST_INLINE=in-line
TEST_OVERRIDE=in-line
TEST_SECRET=secret

@ -1,2 +0,0 @@
📁 Kustomization/default/my-app changed
► ConfigMap/default/my-app created

@ -1,18 +0,0 @@
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: podinfo
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: my-app
namespace: default
spec:
interval: 5m0s
path: ./my-app
force: true
prune: true
sourceRef:
kind: GitRepository
name: podinfo
targetNamespace: default

@ -1,5 +1,5 @@
--- ---
apiVersion: source.toolkit.fluxcd.io/v1 apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: Bucket kind: Bucket
metadata: metadata:
name: flux-system name: flux-system

@ -153,7 +153,7 @@ spec:
name: flux-systen name: flux-systen
namespace: {{ .fluxns }} namespace: {{ .fluxns }}
--- ---
apiVersion: source.toolkit.fluxcd.io/v1 apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: Bucket kind: Bucket
metadata: metadata:
name: flux-system name: flux-system

@ -1,5 +1,5 @@
✚ generating ImagePolicy ✚ generating ImagePolicy
► applying ImagePolicy ► applying ImagePolicy
✔ ImagePolicy created ✔ ImageRepository created
◎ waiting for ImagePolicy reconciliation ◎ waiting for ImagePolicy reconciliation
✔ ImagePolicy reconciliation completed ✔ ImagePolicy reconciliation completed

@ -1,6 +1,6 @@
► resuming kustomization tkfg in {{ .ns }} namespace ► resuming kustomization tkfg in {{ .ns }} namespace
✔ kustomization resumed ✔ kustomization resumed
Kustomization object 'tkfg' not found in {{ .ns }} namespace no Kustomization objects found in {{ .ns }} namespace
◎ waiting for Kustomization reconciliation ◎ waiting for Kustomization reconciliation
✔ Kustomization tkfg reconciliation completed ✔ Kustomization tkfg reconciliation completed
✔ applied revision 6.3.5@sha1:67e2c98a60dc92283531412a9e604dd4bae005a9 ✔ applied revision 6.3.5@sha1:67e2c98a60dc92283531412a9e604dd4bae005a9

@ -1,22 +1,6 @@
//go:build unit //go:build unit
// +build unit // +build unit
/*
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 main package main
import ( import (

@ -43,9 +43,6 @@ The following template can be used for the GitHub release page:
<!-- auto-generated list of pull requests to the CLI starts here --> <!-- auto-generated list of pull requests to the CLI starts here -->
``` ```
Typically, you want to link the [Flux upgrade](https://fluxcd.io/flux/installation/upgrade/)
guide to refer users for up to date information on upgrade options.
In some scenarios, you may want to include specific information about API In some scenarios, you may want to include specific information about API
changes and/or upgrade procedures. Consult [the formatting of changes and/or upgrade procedures. Consult [the formatting of
`v2.0.0-rc.1`](https://github.com/fluxcd/flux2/releases/tag/v2.0.0-rc.1) for `v2.0.0-rc.1`](https://github.com/fluxcd/flux2/releases/tag/v2.0.0-rc.1) for

317
go.mod

@ -1,264 +1,253 @@
module github.com/fluxcd/flux2/v2 module github.com/fluxcd/flux2/v2
go 1.23.0 go 1.22.0
// Fix CVE-2022-28948. // Fix CVE-2022-28948.
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
require ( require (
github.com/Masterminds/semver/v3 v3.3.1 github.com/Masterminds/semver/v3 v3.2.1
github.com/ProtonMail/go-crypto v1.1.5 github.com/ProtonMail/go-crypto v1.0.0
github.com/cyphar/filepath-securejoin v0.4.1 github.com/cyphar/filepath-securejoin v0.2.5
github.com/distribution/distribution/v3 v3.0.0-rc.3 github.com/distribution/distribution/v3 v3.0.0-alpha.1
github.com/fluxcd/cli-utils v0.36.0-flux.12 github.com/fluxcd/cli-utils v0.36.0-flux.7
github.com/fluxcd/go-git-providers v0.22.0 github.com/fluxcd/go-git-providers v0.20.1
github.com/fluxcd/helm-controller/api v1.2.0 github.com/fluxcd/helm-controller/api v1.0.1
github.com/fluxcd/image-automation-controller/api v0.40.0 github.com/fluxcd/image-automation-controller/api v0.38.0
github.com/fluxcd/image-reflector-controller/api v0.34.0 github.com/fluxcd/image-reflector-controller/api v0.32.0
github.com/fluxcd/kustomize-controller/api v1.5.1 github.com/fluxcd/kustomize-controller/api v1.3.0
github.com/fluxcd/notification-controller/api v1.5.0 github.com/fluxcd/notification-controller/api v1.3.0
github.com/fluxcd/pkg/apis/event v0.16.0 github.com/fluxcd/pkg/apis/event v0.9.0
github.com/fluxcd/pkg/apis/meta v1.10.0 github.com/fluxcd/pkg/apis/meta v1.5.0
github.com/fluxcd/pkg/auth v0.3.0 github.com/fluxcd/pkg/envsubst v1.1.0
github.com/fluxcd/pkg/chartutil v1.2.0 github.com/fluxcd/pkg/git v0.19.0
github.com/fluxcd/pkg/envsubst v1.3.0 github.com/fluxcd/pkg/git/gogit v0.19.0
github.com/fluxcd/pkg/git v0.24.0 github.com/fluxcd/pkg/kustomize v1.11.0
github.com/fluxcd/pkg/git/gogit v0.24.0 github.com/fluxcd/pkg/oci v0.37.1
github.com/fluxcd/pkg/kustomize v1.16.0 github.com/fluxcd/pkg/runtime v0.47.1
github.com/fluxcd/pkg/oci v0.45.0 github.com/fluxcd/pkg/sourceignore v0.7.0
github.com/fluxcd/pkg/runtime v0.53.1 github.com/fluxcd/pkg/ssa v0.39.1
github.com/fluxcd/pkg/sourceignore v0.11.0 github.com/fluxcd/pkg/ssh v0.13.0
github.com/fluxcd/pkg/ssa v0.45.0 github.com/fluxcd/pkg/tar v0.7.0
github.com/fluxcd/pkg/ssh v0.17.0 github.com/fluxcd/pkg/version v0.4.0
github.com/fluxcd/pkg/tar v0.11.0 github.com/fluxcd/source-controller/api v1.3.0
github.com/fluxcd/pkg/version v0.6.0 github.com/go-git/go-git/v5 v5.12.0
github.com/fluxcd/source-controller/api v1.5.0 github.com/go-logr/logr v1.4.1
github.com/go-git/go-git/v5 v5.13.2 github.com/gonvenience/bunt v1.3.5
github.com/go-logr/logr v1.4.2 github.com/gonvenience/ytbx v1.4.4
github.com/gonvenience/bunt v1.4.0
github.com/gonvenience/ytbx v1.4.6
github.com/google/go-cmp v0.6.0 github.com/google/go-cmp v0.6.0
github.com/google/go-containerregistry v0.20.3 github.com/google/go-containerregistry v0.19.1
github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-cleanhttp v0.5.2
github.com/homeport/dyff v1.7.1 github.com/homeport/dyff v1.7.1
github.com/lucasb-eyer/go-colorful v1.2.0 github.com/lucasb-eyer/go-colorful v1.2.0
github.com/manifoldco/promptui v0.9.0 github.com/manifoldco/promptui v0.9.0
github.com/mattn/go-shellwords v1.0.12 github.com/mattn/go-shellwords v1.0.12
github.com/notaryproject/notation-go v1.3.0 github.com/notaryproject/notation-go v1.1.0
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/gomega v1.36.2 github.com/onsi/gomega v1.33.1
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/theckman/yacspin v0.13.12 github.com/theckman/yacspin v0.13.12
golang.org/x/crypto v0.36.0 golang.org/x/crypto v0.22.0
golang.org/x/term v0.30.0 golang.org/x/term v0.19.0
golang.org/x/text v0.23.0 golang.org/x/text v0.14.0
k8s.io/api v0.32.2 k8s.io/api v0.30.0
k8s.io/apiextensions-apiserver v0.32.2 k8s.io/apiextensions-apiserver v0.30.0
k8s.io/apimachinery v0.32.2 k8s.io/apimachinery v0.30.0
k8s.io/cli-runtime v0.32.2 k8s.io/cli-runtime v0.30.0
k8s.io/client-go v0.32.2 k8s.io/client-go v0.30.0
k8s.io/kubectl v0.32.2 k8s.io/kubectl v0.30.0
sigs.k8s.io/controller-runtime v0.20.2 sigs.k8s.io/controller-runtime v0.18.1
sigs.k8s.io/kustomize/api v0.19.0 sigs.k8s.io/kustomize/api v0.17.1
sigs.k8s.io/kustomize/kyaml v0.19.0 sigs.k8s.io/kustomize/kyaml v0.17.0
sigs.k8s.io/yaml v1.4.0 sigs.k8s.io/yaml v1.4.0
) )
require ( require (
code.gitea.io/sdk/gitea v0.19.0 // indirect code.gitea.io/sdk/gitea v0.17.1 // indirect
dario.cat/mergo v1.0.1 // indirect dario.cat/mergo v1.0.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect github.com/BurntSushi/toml v1.3.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.35.0 // indirect github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.3 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.11 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.56 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.11 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.26 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.30 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.30 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.40.0 // indirect github.com/aws/aws-sdk-go-v2/service/ecr v1.27.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.11 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.13 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.12 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.11 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 // indirect
github.com/aws/smithy-go v1.22.2 // indirect github.com/aws/smithy-go v1.20.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect
github.com/bradleyfalzon/ghinstallation/v2 v2.13.0 // indirect
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/chzyer/readline v1.5.1 // indirect github.com/chzyer/readline v1.5.1 // indirect
github.com/cloudflare/circl v1.5.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/distribution/reference v0.6.0 // indirect github.com/distribution/reference v0.5.0 // indirect
github.com/docker/cli v27.5.0+incompatible // indirect github.com/docker/cli v24.0.9+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/docker v24.0.9+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-metrics v0.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/emicklei/go-restful/v3 v3.12.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/color v1.16.0 // indirect github.com/fatih/color v1.13.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fluxcd/pkg/apis/acl v0.6.0 // indirect github.com/fluxcd/pkg/apis/acl v0.3.0 // indirect
github.com/fluxcd/pkg/apis/kustomize v1.9.0 // indirect github.com/fluxcd/pkg/apis/kustomize v1.5.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
github.com/go-errors/errors v1.5.1 // indirect github.com/go-errors/errors v1.5.1 // indirect
github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-ldap/ldap/v3 v3.4.10 // indirect github.com/go-ldap/ldap/v3 v3.4.6 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect
github.com/gonvenience/neat v1.3.15 // indirect github.com/gonvenience/neat v1.3.13 // indirect
github.com/gonvenience/term v1.0.3 // indirect github.com/gonvenience/term v1.0.2 // indirect
github.com/gonvenience/text v1.0.8 // indirect github.com/gonvenience/text v1.0.7 // indirect
github.com/google/btree v1.1.3 // indirect github.com/gonvenience/wrap v1.2.0 // indirect
github.com/google/gnostic-models v0.6.9 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/go-github/v66 v66.0.0 // indirect github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-github/v68 v68.0.0 // indirect github.com/google/go-github/v61 v61.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.3 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/compress v1.17.4 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.9.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 // indirect github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/hashstructure v1.1.0 // indirect github.com/mitchellh/hashstructure v1.1.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/term v0.5.0 // indirect github.com/moby/term v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/notaryproject/notation-core-go v1.2.0 // indirect github.com/notaryproject/notation-core-go v1.0.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/common v0.53.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/procfs v0.14.0 // indirect
github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect
github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect
github.com/redis/go-redis/v9 v9.7.0 // indirect github.com/redis/go-redis/v9 v9.1.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect github.com/skeema/knownhosts v1.2.2 // indirect
github.com/spf13/pflag v1.0.6 // indirect github.com/stretchr/objx v0.5.2 // indirect
github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect
github.com/vbatts/tar-split v0.11.6 // indirect github.com/vbatts/tar-split v0.11.3 // indirect
github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/go-gitlab v0.101.0 // indirect
github.com/xanzy/go-gitlab v0.114.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/exporters/autoexport v0.46.1 // indirect
go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 // indirect go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/prometheus v0.54.0 // indirect go.opentelemetry.io/otel/sdk v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 // indirect go.opentelemetry.io/otel/trace v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.opentelemetry.io/otel/log v0.8.0 // indirect go.starlark.net v0.0.0-20231121155337-90ade8b19d09 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
go.opentelemetry.io/otel/sdk v1.33.0 // indirect golang.org/x/mod v0.17.0 // indirect
go.opentelemetry.io/otel/sdk/log v0.8.0 // indirect golang.org/x/net v0.24.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect golang.org/x/sync v0.7.0 // indirect
go.opentelemetry.io/proto/otlp v1.4.0 // indirect golang.org/x/sys v0.19.0 // indirect
golang.org/x/net v0.37.0 // indirect golang.org/x/time v0.5.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect golang.org/x/tools v0.20.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/time v0.9.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.68.1 // indirect google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.36.4 // indirect google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
helm.sh/helm/v3 v3.17.3 // indirect k8s.io/component-base v0.30.0 // indirect
k8s.io/component-base v0.32.2 // indirect k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 // indirect
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect k8s.io/utils v0.0.0-20240310230437-4693a0247e57 // indirect
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
) )

770
go.sum

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save