1
0
mirror of synced 2026-03-01 19:26:55 +00:00

Compare commits

..

53 Commits

Author SHA1 Message Date
Stefan Prodan
5d95a6e750 Merge pull request #2305 from fluxcd/kubectl-1.23.1
Update kubectl to 1.23.1 in flux-cli container image
2022-01-18 19:01:09 +02:00
Stefan Prodan
af00610a61 Update kubectl to 1.23.1 in flux-cli container image
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-18 18:34:16 +02:00
Stefan Prodan
809cb79828 Merge pull request #2304 from fluxcd/fix-release-notes-gen
ci: Fix release notes generator
2022-01-18 18:33:23 +02:00
Stefan Prodan
e44a58cba0 ci: Fix release notes generator
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-18 18:13:59 +02:00
Stefan Prodan
10046187a6 Merge pull request #2301 from fluxcd/cosign
Sign the release artifacts checksums and images
2022-01-18 14:56:47 +02:00
Stefan Prodan
a402461f9c Sign the release artifacts checksums and images
- add the Flux manifests and API schemas to checksums
- sign the checksum.txt with Cosign and GitHub OIDC
- sign the flux-cli container images with Cosign and GitHub OIDC

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-18 14:31:37 +02:00
Stefan Prodan
8a6771c9a9 Merge pull request #2300 from fluxcd/ci-fixes
Fix Azure e2e tests and GoReleaser buildx directive
2022-01-17 11:03:05 +02:00
Stefan Prodan
7173bd5945 Fix GoReleaser buildx directive
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-17 10:37:31 +02:00
Stefan Prodan
8e09ade41c Fix Azure e2e tests
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-17 10:36:03 +02:00
Stefan Prodan
6ceb8d8338 Merge pull request #2295 from fluxcd/sbom-spdx
Publish Flux Software Bill of Materials (SBOM)
2022-01-17 10:33:02 +02:00
Stefan Prodan
11296cd94f Publish Flux Software Bill of Materials (SBOM) in SPDX format
- generate SBOM for Flux Go modules with Syft
- publish the SBOM SPDX JSON files to GitHub releases with GoReleaser

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-14 16:36:49 +02:00
Aurel Canciu
677dca0bc4 Merge pull request #2296 from fluxcd/fix-pkgbuild-envtest
Fix Archlinux PKGBUILD check() run on ARM
2022-01-14 13:55:26 +01:00
Aurel Canciu
8e7b957164 Fix Archlinux PKGBUILD check() run on ARM
The check() run started to fail after #2288 since ENVTEST_ARCH was not
set correctly on ARM/ARM64. This should fix the problem for the flux-go
and flux-scm AUR packages.

Signed-off-by: Aurel Canciu <aurelcanciu@gmail.com>
2022-01-14 13:20:19 +01:00
Stefan Prodan
8f93e2a9d4 Merge pull request #2294 from fluxcd/ci-del-repo
Improve the bootstrap e2e test workflow
2022-01-14 11:48:22 +02:00
Stefan Prodan
62755b4b75 Wait 60s for image automation before failing the test
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-14 10:30:36 +02:00
Stefan Prodan
dcfb745b1f Improve the bootstrap e2e cleanup
Delete the repository regardless of the bootstrap test exit code.

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-13 20:44:02 +02:00
Stefan Prodan
f38b83231c Merge pull request #2291 from fluxcd/update-components
Update kustomize-controller to v0.19.1
2022-01-13 20:33:47 +02:00
fluxcdbot
269f5e2575 Update toolkit components
- kustomize-controller to v0.19.1
  https://github.com/fluxcd/kustomize-controller/blob/v0.19.1/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2022-01-13 18:17:27 +00:00
Stefan Prodan
893596383a Merge pull request #2290 from fluxcd/ssa-v0.10.0
Update dependencies
2022-01-13 19:56:47 +02:00
Stefan Prodan
8c67708829 Update dependencies
- sigs.k8s.io/cli-utils v0.27.0
- github.com/fluxcd/pkg/ssa v0.10.0

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-13 19:37:14 +02:00
Stefan Prodan
c1528503b6 Merge pull request #2141 from schrej/feature/trace-simpler-arguments
Simplify arguments of flux trace command
2022-01-13 19:36:56 +02:00
Jakob Schrettenbrunner
d3c56eb3d3 trace: fix lint warning
Signed-off-by: Jakob Schrettenbrunner <jakob.schrettenbrunner@telekom.de>
2022-01-13 15:52:47 +01:00
Jakob Schrettenbrunner
b10eee87ee Simplify arguments of flux trace command
It now accepts arguments in the forms <resource>/<name>
and <resource> <name> instead of requiring api version and
kind as flags.

Signed-off-by: Jakob Schrettenbrunner <jakob.schrettenbrunner@telekom.de>
2022-01-13 15:52:47 +01:00
Hidde Beydals
83de469967 Merge pull request #2267 from tomalexander/add_git_build_dep 2022-01-13 15:22:23 +01:00
Tom Alexander
192978125f build/aur: fix the make target for the manifests
Signed-off-by: Tom Alexander <tom@fizz.buzz>
2022-01-13 14:58:46 +01:00
Tom Alexander
b4b3551e39 build/aur: add Git as flux-scm build dependency
Without git installed, makepkg fails to fetch the source. This breaks
the build for people who build their aur packages inside temporary
containers (for example aurutils with the -c flag).

Signed-off-by: Tom Alexander <tom@fizz.buzz>
2022-01-13 14:58:33 +01:00
Stefan Prodan
7f580e89d0 Merge pull request #2288 from aryan9600/aryan9600/setup-testenv
Fix makefile envtest setup and usage
2022-01-13 13:10:17 +02:00
Sanskar Jaiswal
81a087095a fix makefile envtest setup and usage
Refactor logic to install helper tools into one function in the
Makefile. Add support for envtest to help install tools like kubectl,
etcd which helps users run tests more conveniently.

Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
2022-01-13 16:09:11 +05:30
Hidde Beydals
bcabde3bdb Merge pull request #2231 from achetronic/fix-bootstrap-https-port-overwrite 2022-01-13 11:02:22 +01:00
Alby Hernández
c190d80d4a Avoid overwriting the host port on http requests
Remove the overwrite of the repositoryURL.Host variable to include Git
servers deployed on non-standard https ports

Co-authored-by: Sebastián Vargas <develolux@gmail.com>

Signed-off-by: Alby Hernández <me@achetronic.com>
Signed-off-by: Alby Hernández <alby.hernandez@system73.com>
2022-01-13 10:32:10 +01:00
Stefan Prodan
11081e8cb2 Merge pull request #2285 from souleb/issue-2284
Update go-git-provider to fix GitLab bootstrap regression bug
2022-01-12 18:19:23 +02:00
Soule BA
c5890f08ef reverting go-git-provider to fix #2284
Signed-off-by: Soule BA <soule@weave.works>
2022-01-12 16:51:35 +01:00
Stefan Prodan
926d8a1c37 Merge pull request #2234 from souleb/issue-2207
Use provided SSH hostname to sync with SSH
2022-01-12 13:18:52 +02:00
Soule BA
da6dfd5a1b Use provided ssh hostname to sync with ssh
Signed-off-by: Soule BA <soule@weave.works>
2022-01-12 11:52:17 +01:00
Stefan Prodan
4318152141 Merge pull request #2281 from Skarlso/add_bindir_to_action
Add optional bindir input to Flux GitHub Action
2022-01-12 12:03:04 +02:00
Gergely Brautigam
759145704f Update the action to include an optional bindir
Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
2022-01-12 10:38:19 +01:00
Stefan Prodan
5cab8f4b11 Merge pull request #2280 from fluxcd/go-git-providers-v0.5.1
Update Git providers
2022-01-12 11:11:36 +02:00
Stefan Prodan
a0ce4b23d2 Update Git providers
- go-git-providers v0.5.1
- go-github v41.0.0
- go-gitlab v0.54.3

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-12 10:34:58 +02:00
Hidde Beydals
6d88a0c3ac Merge pull request #2278 from fluxcd/update-components 2022-01-11 18:22:19 +01:00
fluxcdbot
db44bcd88e Update toolkit components
- notification-controller to v0.20.1
  https://github.com/fluxcd/notification-controller/blob/v0.20.1/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2022-01-11 14:36:35 +00:00
Hidde Beydals
585ae5090d Merge pull request #2272 from fluxcd/x-crypto-patch 2022-01-10 19:32:32 +01:00
Hidde Beydals
fe46793c40 Update golang.org/x/crypto to latest main
This includes the full commit tree to solve both CVE-2020-29652 and
CVE-2021-43565:
8b5274cf68...5770296d90

Signed-off-by: Hidde Beydals <hello@hidde.co>
2022-01-10 19:02:47 +01:00
Stefan Prodan
be146b1cc9 Merge pull request #2271 from fluxcd/update-components-pkg
Update toolkit components and packages
2022-01-10 19:16:21 +02:00
Aurel Canciu
e46c7bd519 Update golang.org/x/crypto to fix CVE-2020-29652
Signed-off-by: Aurel Canciu <aurelcanciu@gmail.com>
2022-01-10 17:47:23 +01:00
Aurel Canciu
f3d143e5ee Update Go to v1.17
Signed-off-by: Aurel Canciu <aurelcanciu@gmail.com>
2022-01-10 16:30:38 +01:00
Stefan Prodan
fc059df8ff Update controller-runtime dependencies
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-01-10 16:54:53 +02:00
fluxcdbot
6c047d1e2a Update toolkit components
- helm-controller to v0.15.0
  https://github.com/fluxcd/helm-controller/blob/v0.15.0/CHANGELOG.md
- kustomize-controller to v0.19.0
  https://github.com/fluxcd/kustomize-controller/blob/v0.19.0/CHANGELOG.md
- source-controller to v0.20.1
  https://github.com/fluxcd/source-controller/blob/v0.20.1/CHANGELOG.md
- image-reflector-controller to v0.15.0
  https://github.com/fluxcd/image-reflector-controller/blob/v0.15.0/CHANGELOG.md
- image-automation-controller to v0.19.0
  https://github.com/fluxcd/image-automation-controller/blob/v0.19.0/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2022-01-10 14:35:39 +00:00
Stefan Prodan
f6afe7f0ec Merge pull request #2144 from schrej/feature/cli-runtime
Use k8s.io/cli-runtime for kubernetes flags
2022-01-10 11:39:15 +02:00
Jakob Schrettenbrunner
ca7d2e783f Use k8s.io/cli-runtime for kubernetes flags
Signed-off-by: Jakob Schrettenbrunner <jakob.schrettenbrunner@telekom.de>
2022-01-07 16:01:24 +01:00
Max Jonas Werner
0b133ca9f2 Merge pull request #2212 from fluxcd/rfc-0001-extra
[RFC-0001] Memorandum on the authorization model
2021-12-21 13:01:56 +01:00
Michael Bridgen
ede6785e6b RFC on authorisation model
This gives a baseline for future changes, e.g., expanding where
namespace ACLs are used, switching access control to
untrusted-by-default.

The "Security considerations" section  was adapted from

    https://github.com/fluxcd/flux2/pull/2086

Signed-off-by: Michael Bridgen <michael@weave.works>
2021-12-17 19:17:25 +00:00
Stefan Prodan
6d9f39d8ea Merge pull request #2223 from fluxcd/arm64-helm
Add the Helm CLI to the GitHub ARM64 runners setup
2021-12-17 13:16:02 +02:00
Stefan Prodan
fb637ea955 Add the Helm CLI to the GitHub ARM64 runners setup
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-12-17 12:33:27 +02:00
101 changed files with 1472 additions and 1084 deletions

View File

@@ -12,7 +12,7 @@ provides=("flux-bin")
conflicts=("flux-bin")
replaces=("flux-cli")
depends=("glibc")
makedepends=('go>=1.16', 'kustomize>=3.0')
makedepends=('go>=1.17', 'kustomize>=3.0')
optdepends=('bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source=(
@@ -30,12 +30,20 @@ build() {
export CGO_CXXFLAGS="$CXXFLAGS"
export CGO_CPPFLAGS="$CPPFLAGS"
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
./manifests/scripts/bundle.sh "${PWD}/manifests" "${PWD}/cmd/flux/manifests"
make cmd/flux/.manifests.done
go build -ldflags "-linkmode=external -X main.VERSION=${pkgver}" -o ${_srcname} ./cmd/flux
}
check() {
cd "flux2-${pkgver}"
case $CARCH in
aarch64)
export ENVTEST_ARCH=arm64
;;
armv6h|armv7h)
export ENVTEST_ARCH=arm
;;
esac
make test
}

View File

@@ -11,7 +11,7 @@ license=("APACHE")
provides=("flux-bin")
conflicts=("flux-bin")
depends=("glibc")
makedepends=('go>=1.16', 'kustomize>=3.0')
makedepends=('go>=1.17', 'kustomize>=3.0', 'git')
optdepends=('bash-completion: auto-completion for flux in Bash',
'zsh-completions: auto-completion for flux in ZSH')
source=(
@@ -32,12 +32,20 @@ build() {
export CGO_CXXFLAGS="$CXXFLAGS"
export CGO_CPPFLAGS="$CPPFLAGS"
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
make cmd/flux/manifests
make cmd/flux/.manifests.done
go build -ldflags "-linkmode=external -X main.VERSION=${pkgver}" -o ${_srcname} ./cmd/flux
}
check() {
cd "flux2"
case $CARCH in
aarch64)
export ENVTEST_ARCH=arm64
;;
armv6h|armv7h)
export ENVTEST_ARCH=arm
;;
esac
make test
}

View File

@@ -21,6 +21,7 @@ set -eu
KIND_VERSION=0.11.1
KUBECTL_VERSION=1.21.2
KUSTOMIZE_VERSION=4.1.3
HELM_VERSION=3.7.2
GITHUB_RUNNER_VERSION=2.285.1
PACKAGES="apt-transport-https ca-certificates software-properties-common build-essential libssl-dev gnupg lsb-release jq"
@@ -52,6 +53,12 @@ curl -Lo ./kustomize.tar.gz https://github.com/kubernetes-sigs/kustomize/release
&& rm kustomize.tar.gz
install -o root -g root -m 0755 kustomize /usr/local/bin/kustomize
# install helm
curl -Lo ./helm.tar.gz https://get.helm.sh/helm-v${HELM_VERSION}-linux-arm64.tar.gz \
&& tar -zxvf helm.tar.gz \
&& rm helm.tar.gz
install -o root -g root -m 0755 linux-arm64/helm /usr/local/bin/helm
# download runner
curl -o actions-runner-linux-arm64.tar.gz -L https://github.com/actions/runner/releases/download/v${GITHUB_RUNNER_VERSION}/actions-runner-linux-arm64-${GITHUB_RUNNER_VERSION}.tar.gz \
&& tar xzf actions-runner-linux-arm64.tar.gz \

View File

@@ -17,13 +17,13 @@ jobs:
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go1.16-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go1.17-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go1.16-
${{ runner.os }}-go1.17-
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
go-version: 1.17.x
- name: Setup Kubernetes
uses: engineerd/setup-kind@v0.5.0
with:
@@ -103,13 +103,26 @@ jobs:
/tmp/flux reconcile image repository podinfo
/tmp/flux reconcile image update flux-system
/tmp/flux get images all
/tmp/flux get images policy podinfo | grep "5.2.1"
/tmp/flux get image update flux-system | grep commit
retries=10
count=0
ok=false
until ${ok}; do
/tmp/flux get image update flux-system | grep 'commit' && ok=true || ok=false
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
echo "No more retries left"
exit 1
fi
sleep 6
/tmp/flux reconcile image update flux-system
done
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
GITHUB_REPO_NAME: ${{ steps.vars.outputs.test_repo_name }}
GITHUB_ORG_NAME: fluxcd-testing
- name: delete repository
if: ${{ always() }}
run: |
curl \
-X DELETE \

View File

@@ -16,7 +16,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
go-version: 1.17.x
- name: Prepare
id: prep
run: |

View File

@@ -17,13 +17,13 @@ jobs:
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go1.16-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go1.17-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go1.16-
${{ runner.os }}-go1.17-
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
go-version: 1.17.x
- name: Install libgit2
run: |
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 648ACFD622F3D138

View File

@@ -16,23 +16,19 @@ jobs:
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go1.16-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go1.17-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go1.16-
${{ runner.os }}-go1.17-
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
go-version: 1.17.x
- name: Setup Kubernetes
uses: engineerd/setup-kind@v0.5.0
with:
version: v0.11.1
image: kindest/node:v1.19.11@sha256:07db187ae84b4b7de440a73886f008cf903fcf5764ba8106a9fd5243d6f32729
config: .github/kind/config.yaml # disable KIND-net
- name: Setup envtest
uses: fluxcd/pkg/actions/envtest@main
with:
version: "1.21.x"
- name: Setup Calico for network policy
run: |
kubectl apply -f https://docs.projectcalico.org/v3.20/manifests/calico.yaml

View File

@@ -4,6 +4,11 @@ on:
push:
tags: [ 'v*' ]
permissions:
contents: write # needed to write releases
id-token: write # needed for keyless signing
packages: write # needed for ghcr access
jobs:
goreleaser:
runs-on: ubuntu-latest
@@ -15,16 +20,18 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
go-version: 1.17.x
- name: Setup QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
buildkitd-flags: "--debug"
- name: Setup Syft
uses: anchore/sbom-action/download-syft@v0
- name: Setup Cosign
uses: sigstore/cosign-installer@main
- name: Setup Kustomize
uses: fluxcd/pkg//actions/kustomize@main
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
@@ -36,18 +43,6 @@ jobs:
with:
username: fluxcdbot
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
- 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: |
echo 'CHANGELOG' > /tmp/release.txt
github-release-notes -org fluxcd -repo toolkit -since-latest-release -include-author >> /tmp/release.txt
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Kustomize
uses: fluxcd/pkg//actions/kustomize@main
- name: Generate manifests
run: |
make cmd/flux/.manifests.done
@@ -66,11 +61,22 @@ jobs:
- name: Archive the OpenAPI JSON schemas
run: |
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
uses: goreleaser/goreleaser-action@v1
with:
version: latest
args: release --release-notes=/tmp/release.txt --skip-validate
args: release --release-notes=output/notes.md --skip-validate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}

View File

@@ -16,7 +16,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.16.x
go-version: 1.17.x
- name: Update component versions
id: update
run: |

1
.gitignore vendored
View File

@@ -20,6 +20,7 @@ bin/
output/
cmd/flux/manifests/
cmd/flux/.manifests.done
testbin/
# Docs
site/

View File

@@ -40,6 +40,36 @@ archives:
format: zip
files:
- none*
source:
enabled: true
name_template: '{{ .ProjectName }}_{{ .Version }}_source_code'
sboms:
- id: source
artifacts: source
documents:
- "{{ .ProjectName }}_{{ .Version }}_sbom.spdx.json"
release:
extra_files:
- glob: output/crd-schemas.tar.gz
- glob: output/manifests.tar.gz
- glob: output/install.yaml
checksum:
extra_files:
- glob: output/crd-schemas.tar.gz
- glob: output/manifests.tar.gz
- glob: output/install.yaml
signs:
- cmd: cosign
env:
- COSIGN_EXPERIMENTAL=1
certificate: '${artifact}.pem'
args:
- sign-blob
- '--output-certificate=${certificate}'
- '--output-signature=${signature}'
- '${artifact}'
artifacts: checksum
output: true
brews:
- name: flux
tap:
@@ -78,17 +108,12 @@ publishers:
- AUR_BOT_SSH_PRIVATE_KEY={{ .Env.AUR_BOT_SSH_PRIVATE_KEY }}
cmd: |
.github/aur/flux-go/publish.sh {{ .Version }}
release:
extra_files:
- glob: ./output/crd-schemas.tar.gz
- glob: ./output/manifests.tar.gz
- glob: ./output/install.yaml
dockers:
- image_templates:
- 'fluxcd/flux-cli:{{ .Tag }}-amd64'
- 'ghcr.io/fluxcd/flux-cli:{{ .Tag }}-amd64'
dockerfile: Dockerfile
use_buildx: true
use: buildx
goos: linux
goarch: amd64
build_flag_templates:
@@ -104,7 +129,7 @@ dockers:
- 'fluxcd/flux-cli:{{ .Tag }}-arm64'
- 'ghcr.io/fluxcd/flux-cli:{{ .Tag }}-arm64'
dockerfile: Dockerfile
use_buildx: true
use: buildx
goos: linux
goarch: arm64
build_flag_templates:
@@ -120,7 +145,7 @@ dockers:
- 'fluxcd/flux-cli:{{ .Tag }}-arm'
- 'ghcr.io/fluxcd/flux-cli:{{ .Tag }}-arm'
dockerfile: Dockerfile
use_buildx: true
use: buildx
goos: linux
goarch: arm
goarm: 7
@@ -144,3 +169,12 @@ docker_manifests:
- 'ghcr.io/fluxcd/flux-cli:{{ .Tag }}-amd64'
- 'ghcr.io/fluxcd/flux-cli:{{ .Tag }}-arm64'
- 'ghcr.io/fluxcd/flux-cli:{{ .Tag }}-arm'
docker_signs:
- cmd: cosign
env:
- COSIGN_EXPERIMENTAL=1
args:
- sign
- '${artifact}'
artifacts: all
output: true

View File

@@ -1,15 +1,15 @@
FROM alpine:3.14 as builder
FROM alpine:3.15 as builder
RUN apk add --no-cache ca-certificates curl
ARG ARCH=linux/amd64
ARG KUBECTL_VER=1.22.2
ARG KUBECTL_VER=1.23.1
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 && \
kubectl version --client=true
FROM alpine:3.14 as flux-cli
FROM alpine:3.15 as flux-cli
# Create minimal nsswitch.conf file to prioritize the usage of /etc/hosts over DNS queries.
# https://github.com/gliderlabs/docker-alpine/issues/367#issuecomment-354316460

View File

@@ -1,8 +1,8 @@
VERSION?=$(shell grep 'VERSION' cmd/flux/main.go | awk '{ print $$4 }' | head -n 1 | tr -d '"')
EMBEDDED_MANIFESTS_TARGET=cmd/flux/.manifests.done
TEST_KUBECONFIG?=/tmp/flux-e2e-test-kubeconfig
ENVTEST_BIN_VERSION?=latest
KUBEBUILDER_ASSETS?=$(shell $(SETUP_ENVTEST) use -i $(ENVTEST_BIN_VERSION) -p path)
# Architecture to use envtest with
ENVTEST_ARCH ?= amd64
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
@@ -17,6 +17,7 @@ all: test build
tidy:
go mod tidy
cd tests/azure && go mod tidy
fmt:
go fmt ./...
@@ -33,6 +34,7 @@ cleanup-kind:
kind delete cluster --name=flux-e2e-test
rm $(TEST_KUBECONFIG)
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
test: $(EMBEDDED_MANIFESTS_TARGET) tidy fmt vet install-envtest
KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test ./... -coverprofile cover.out --tags=unit
@@ -58,27 +60,33 @@ install:
install-dev:
CGO_ENABLED=0 go build -o /usr/local/bin ./cmd/flux
install-envtest: setup-envtest
$(SETUP_ENVTEST) use $(ENVTEST_BIN_VERSION)
setup-bootstrap-patch:
go run ./tests/bootstrap/main.go
setup-image-automation:
cd tests/image-automation && go run main.go
# Find or download setup-envtest
setup-envtest:
ifeq (, $(shell which setup-envtest))
@{ \
set -e ;\
SETUP_ENVTEST_TMP_DIR=$$(mktemp -d) ;\
cd $$SETUP_ENVTEST_TMP_DIR ;\
go mod init tmp ;\
go get sigs.k8s.io/controller-runtime/tools/setup-envtest@latest ;\
rm -rf $$SETUP_ENVTEST_TMP_DIR ;\
}
SETUP_ENVTEST=$(GOBIN)/setup-envtest
else
SETUP_ENVTEST=$(shell which setup-envtest)
endif
ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
ENVTEST_KUBERNETES_VERSION?=latest
install-envtest: setup-envtest
mkdir -p ${ENVTEST_ASSETS_DIR}
$(ENVTEST) use $(ENVTEST_KUBERNETES_VERSION) --arch=$(ENVTEST_ARCH) --bin-dir=$(ENVTEST_ASSETS_DIR)
ENVTEST = $(shell pwd)/bin/setup-envtest
.PHONY: envtest
setup-envtest: ## Download envtest-setup locally if necessary.
$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest)
# go-install-tool will 'go install' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
define go-install-tool
@[ -f $(1) ] || { \
set -e ;\
TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef

View File

@@ -12,6 +12,9 @@ inputs:
description: "arch can be amd64, arm64 or arm"
required: true
default: "amd64"
bindir:
description: "Optional location of the Flux binary. Will not use sudo if set. Updates System Path."
required: false
runs:
using: composite
steps:
@@ -29,10 +32,16 @@ runs:
curl -sL ${BIN_URL} -o /tmp/flux.tar.gz
mkdir -p /tmp/flux
tar -C /tmp/flux/ -zxvf /tmp/flux.tar.gz
- name: "Add flux binary to /usr/local/bin"
- name: "Copy Flux binary to execute location"
shell: bash
run: |
sudo cp /tmp/flux/flux /usr/local/bin
BINDIR=${{ inputs.bindir }}
if [ -z $BINDIR ]; then
sudo cp /tmp/flux/flux /usr/local/bin
else
cp /tmp/flux/flux "${BINDIR}"
echo "${BINDIR}" >> $GITHUB_PATH
fi
- name: "Cleanup tmp"
shell: bash
run: |

View File

@@ -121,7 +121,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -179,7 +179,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
installOptions := install.Options{
BaseURL: rootArgs.defaults.BaseURL,
Version: bootstrapArgs.version,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Components: bootstrapComponents(),
Registry: bootstrapArgs.registry,
ImagePullSecret: bootstrapArgs.imagePullSecret,
@@ -200,7 +200,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
// Source generation and secret config
secretOpts := sourcesecret.Options{
Name: bootstrapArgs.secretName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
TargetPath: bServerArgs.path.String(),
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
}
@@ -232,8 +232,8 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
// Sync manifest config
syncOpts := sync.Options{
Interval: bServerArgs.interval,
Name: rootArgs.namespace,
Namespace: rootArgs.namespace,
Name: *kubeconfigArgs.Namespace,
Namespace: *kubeconfigArgs.Namespace,
Branch: bootstrapArgs.branch,
Secret: bootstrapArgs.secretName,
TargetPath: bServerArgs.path.ToSlash(),
@@ -251,7 +251,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
bootstrap.WithProviderTeamPermissions(mapTeamSlice(bServerArgs.teams, bServerDefaultPermission)),
bootstrap.WithReadWriteKeyPermissions(bServerArgs.readWriteKey),
bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
bootstrap.WithKubeconfig(kubeconfigArgs),
bootstrap.WithLogger(logger),
bootstrap.WithCABundle(caBundle),
}

View File

@@ -101,7 +101,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -128,7 +128,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
installOptions := install.Options{
BaseURL: rootArgs.defaults.BaseURL,
Version: bootstrapArgs.version,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Components: bootstrapComponents(),
Registry: bootstrapArgs.registry,
ImagePullSecret: bootstrapArgs.imagePullSecret,
@@ -149,7 +149,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
// Source generation and secret config
secretOpts := sourcesecret.Options{
Name: bootstrapArgs.secretName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
TargetPath: gitArgs.path.String(),
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
}
@@ -161,10 +161,15 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
secretOpts.CAFilePath = bootstrapArgs.caFile
}
// 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
if repositoryURL.Scheme != "https" && repositoryURL.Scheme != "http" {
repositoryURL.Host = repositoryURL.Hostname()
}
// Configure repository URL to match auth config for sync.
repositoryURL.User = nil
repositoryURL.Scheme = "https"
repositoryURL.Host = repositoryURL.Hostname()
} else {
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
secretOpts.Password = gitArgs.password
@@ -194,8 +199,8 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
// Sync manifest config
syncOpts := sync.Options{
Interval: gitArgs.interval,
Name: rootArgs.namespace,
Namespace: rootArgs.namespace,
Name: *kubeconfigArgs.Namespace,
Namespace: *kubeconfigArgs.Namespace,
URL: repositoryURL.String(),
Branch: bootstrapArgs.branch,
Secret: bootstrapArgs.secretName,
@@ -220,7 +225,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
bootstrap.WithBranch(bootstrapArgs.branch),
bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail),
bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
bootstrap.WithKubeconfig(kubeconfigArgs),
bootstrap.WithPostGenerateSecretFunc(promptPublicKey),
bootstrap.WithLogger(logger),
bootstrap.WithCABundle(caBundle),

View File

@@ -125,7 +125,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -175,7 +175,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
installOptions := install.Options{
BaseURL: rootArgs.defaults.BaseURL,
Version: bootstrapArgs.version,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Components: bootstrapComponents(),
Registry: bootstrapArgs.registry,
ImagePullSecret: bootstrapArgs.imagePullSecret,
@@ -196,7 +196,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
// Source generation and secret config
secretOpts := sourcesecret.Options{
Name: bootstrapArgs.secretName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
TargetPath: githubArgs.path.ToSlash(),
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
}
@@ -221,8 +221,8 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
// Sync manifest config
syncOpts := sync.Options{
Interval: githubArgs.interval,
Name: rootArgs.namespace,
Namespace: rootArgs.namespace,
Name: *kubeconfigArgs.Namespace,
Namespace: *kubeconfigArgs.Namespace,
Branch: bootstrapArgs.branch,
Secret: bootstrapArgs.secretName,
TargetPath: githubArgs.path.ToSlash(),
@@ -240,7 +240,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
bootstrap.WithProviderTeamPermissions(mapTeamSlice(githubArgs.teams, ghDefaultPermission)),
bootstrap.WithReadWriteKeyPermissions(githubArgs.readWriteKey),
bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
bootstrap.WithKubeconfig(kubeconfigArgs),
bootstrap.WithLogger(logger),
bootstrap.WithCABundle(caBundle),
}

View File

@@ -129,7 +129,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -186,7 +186,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
installOptions := install.Options{
BaseURL: rootArgs.defaults.BaseURL,
Version: bootstrapArgs.version,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Components: bootstrapComponents(),
Registry: bootstrapArgs.registry,
ImagePullSecret: bootstrapArgs.imagePullSecret,
@@ -207,7 +207,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
// Source generation and secret config
secretOpts := sourcesecret.Options{
Name: bootstrapArgs.secretName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
TargetPath: gitlabArgs.path.String(),
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
}
@@ -235,8 +235,8 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
// Sync manifest config
syncOpts := sync.Options{
Interval: gitlabArgs.interval,
Name: rootArgs.namespace,
Namespace: rootArgs.namespace,
Name: *kubeconfigArgs.Namespace,
Namespace: *kubeconfigArgs.Namespace,
Branch: bootstrapArgs.branch,
Secret: bootstrapArgs.secretName,
TargetPath: gitlabArgs.path.ToSlash(),
@@ -254,7 +254,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
bootstrap.WithProviderTeamPermissions(mapTeamSlice(gitlabArgs.teams, glDefaultPermission)),
bootstrap.WithReadWriteKeyPermissions(gitlabArgs.readWriteKey),
bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
bootstrap.WithKubeconfig(kubeconfigArgs),
bootstrap.WithLogger(logger),
bootstrap.WithCABundle(caBundle),
}

View File

@@ -128,7 +128,7 @@ func fluxCheck() {
}
func kubernetesCheck(constraints []string) bool {
cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
cfg, err := utils.KubeConfig(kubeconfigArgs)
if err != nil {
logger.Failuref("Kubernetes client initialization failed: %s", err.Error())
return false
@@ -176,7 +176,7 @@ func componentsCheck() bool {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeConfig, err := utils.KubeConfig(kubeconfigArgs)
if err != nil {
return false
}
@@ -186,7 +186,7 @@ func componentsCheck() bool {
return false
}
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return false
}
@@ -194,7 +194,7 @@ func componentsCheck() bool {
ok := true
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
var list v1.DeploymentList
if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err == nil {
if err := kubeClient.List(ctx, &list, client.InNamespace(*kubeconfigArgs.Namespace), selector); err == nil {
for _, d := range list.Items {
if ref, err := buildComponentObjectRefs(d.Name); err == nil {
if err := statusChecker.Assess(ref...); err != nil {

View File

@@ -1,3 +1,4 @@
//go:build e2e
// +build e2e
/*
@@ -29,7 +30,7 @@ import (
)
func TestCheckPre(t *testing.T) {
jsonOutput, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, "version", "--output", "json")
jsonOutput, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, "version", "--output", "json")
if err != nil {
t.Fatalf("Error running utils.ExecKubectlCommand: %v", err.Error())
}

View File

@@ -25,10 +25,7 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
memory "k8s.io/client-go/discovery/cached"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/restmapper"
)
var completionCmd = &cobra.Command{
@@ -42,7 +39,7 @@ func init() {
}
func contextsCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
rawConfig, err := utils.ClientConfig(rootArgs.kubeconfig, rootArgs.kubecontext).RawConfig()
rawConfig, err := kubeconfigArgs.ToRawKubeConfigLoader().RawConfig()
if err != nil {
return completionError(err)
}
@@ -63,16 +60,15 @@ func resourceNamesCompletionFunc(gvk schema.GroupVersionKind) func(cmd *cobra.Co
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
cfg, err := utils.KubeConfig(kubeconfigArgs)
if err != nil {
return completionError(err)
}
dc, err := discovery.NewDiscoveryClientForConfig(cfg)
mapper, err := kubeconfigArgs.ToRESTMapper()
if err != nil {
return completionError(err)
}
mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc))
mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
@@ -86,7 +82,7 @@ func resourceNamesCompletionFunc(gvk schema.GroupVersionKind) func(cmd *cobra.Co
var dr dynamic.ResourceInterface
if mapping.Scope.Name() == meta.RESTScopeNameNamespace {
dr = client.Resource(mapping.Resource).Namespace(rootArgs.namespace)
dr = client.Resource(mapping.Resource).Namespace(*kubeconfigArgs.Namespace)
} else {
dr = client.Resource(mapping.Resource)
}

View File

@@ -104,7 +104,7 @@ func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) e
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) // NB globals
kubeClient, err := utils.KubeClient(kubeconfigArgs) // NB globals
if err != nil {
return err
}

View File

@@ -102,7 +102,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error {
alert := notificationv1.Alert{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
Spec: notificationv1.AlertSpec{
@@ -122,7 +122,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}

View File

@@ -94,7 +94,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error {
provider := notificationv1.Provider{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
Spec: notificationv1.ProviderSpec{
@@ -118,7 +118,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}

View File

@@ -160,7 +160,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
helmRelease := helmv2.HelmRelease{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
Spec: helmv2.HelmReleaseSpec{
@@ -250,7 +250,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}

View File

@@ -101,7 +101,7 @@ func createImagePolicyRun(cmd *cobra.Command, args []string) error {
var policy = imagev1.ImagePolicy{
ObjectMeta: metav1.ObjectMeta{
Name: objectName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: labels,
},
Spec: imagev1.ImagePolicySpec{

View File

@@ -104,7 +104,7 @@ func createImageRepositoryRun(cmd *cobra.Command, args []string) error {
var repo = imagev1.ImageRepository{
ObjectMeta: metav1.ObjectMeta{
Name: objectName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: labels,
},
Spec: imagev1.ImageRepositorySpec{

View File

@@ -108,7 +108,7 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
var update = autov1.ImageUpdateAutomation{
ObjectMeta: metav1.ObjectMeta{
Name: objectName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: labels,
},
Spec: autov1.ImageUpdateAutomationSpec{

View File

@@ -143,7 +143,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
kustomization := kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: kslabels,
},
Spec: kustomizev1.KustomizationSpec{
@@ -232,7 +232,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}

View File

@@ -109,7 +109,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error {
receiver := notificationv1.Receiver{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
Spec: notificationv1.ReceiverSpec{
@@ -130,7 +130,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}

View File

@@ -132,7 +132,7 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
opts := sourcesecret.Options{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: labels,
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
}
@@ -176,14 +176,14 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
if err := upsertSecret(ctx, kubeClient, s); err != nil {
return err
}
logger.Actionf("git secret '%s' created in '%s' namespace", name, rootArgs.namespace)
logger.Actionf("git secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace)
return nil
}

View File

@@ -80,7 +80,7 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error {
opts := sourcesecret.Options{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: labels,
Username: secretHelmArgs.username,
Password: secretHelmArgs.password,
@@ -100,7 +100,7 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -112,6 +112,6 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error {
return err
}
logger.Actionf("helm secret '%s' created in '%s' namespace", name, rootArgs.namespace)
logger.Actionf("helm secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace)
return nil
}

View File

@@ -79,7 +79,7 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error {
opts := sourcesecret.Options{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: labels,
CAFilePath: secretTLSArgs.caFile,
CertFilePath: secretTLSArgs.certFile,
@@ -97,7 +97,7 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -109,6 +109,6 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error {
return err
}
logger.Actionf("tls secret '%s' created in '%s' namespace", name, rootArgs.namespace)
logger.Actionf("tls secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace)
return nil
}

View File

@@ -120,7 +120,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
bucket := &sourcev1.Bucket{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
Spec: sourcev1.BucketSpec{
@@ -152,7 +152,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -165,7 +165,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
StringData: map[string]string{},

View File

@@ -193,7 +193,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
gitRepository := sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
Spec: sourcev1.GitRepositorySpec{
@@ -235,7 +235,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -244,7 +244,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
if sourceGitArgs.secretRef == "" {
secretOpts := sourcesecret.Options{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
}
switch u.Scheme {

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
/*

View File

@@ -118,7 +118,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
helmRepository := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Labels: sourceLabels,
},
Spec: sourcev1.HelmRepositorySpec{
@@ -147,7 +147,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
@@ -157,7 +157,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
secretName := fmt.Sprintf("helm-%s", name)
secretOpts := sourcesecret.Options{
Name: secretName,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Username: sourceHelmArgs.username,
Password: sourceHelmArgs.password,
CertFilePath: sourceHelmArgs.certFile,

View File

@@ -159,7 +159,7 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}

View File

@@ -60,13 +60,13 @@ func (del deleteCommand) run(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
namespacedName := types.NamespacedName{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
@@ -85,7 +85,7 @@ func (del deleteCommand) run(cmd *cobra.Command, args []string) error {
}
}
logger.Actionf("deleting %s %s in %s namespace", del.humanKind, name, rootArgs.namespace)
logger.Actionf("deleting %s %s in %s namespace", del.humanKind, name, *kubeconfigArgs.Namespace)
err = kubeClient.Delete(ctx, del.object.asClientObject())
if err != nil {
return err

View File

@@ -20,6 +20,7 @@ import (
"bytes"
"context"
"fmt"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -73,19 +74,19 @@ func (export exportCommand) run(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
if exportArgs.all {
err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(rootArgs.namespace))
err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(*kubeconfigArgs.Namespace))
if err != nil {
return err
}
if export.list.len() == 0 {
return fmt.Errorf("no objects found in %s namespace", rootArgs.namespace)
return fmt.Errorf("no objects found in %s namespace", *kubeconfigArgs.Namespace)
}
for i := 0; i < export.list.len(); i++ {
@@ -96,7 +97,7 @@ func (export exportCommand) run(cmd *cobra.Command, args []string) error {
} else {
name := args[0]
namespacedName := types.NamespacedName{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
err = kubeClient.Get(ctx, namespacedName, export.object.asClientObject())

View File

@@ -19,6 +19,7 @@ package main
import (
"context"
"fmt"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -58,19 +59,19 @@ func (export exportWithSecretCommand) run(cmd *cobra.Command, args []string) err
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
if exportArgs.all {
err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(rootArgs.namespace))
err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(*kubeconfigArgs.Namespace))
if err != nil {
return err
}
if export.list.len() == 0 {
return fmt.Errorf("no objects found in %s namespace", rootArgs.namespace)
return fmt.Errorf("no objects found in %s namespace", *kubeconfigArgs.Namespace)
}
for i := 0; i < export.list.len(); i++ {
@@ -88,7 +89,7 @@ func (export exportWithSecretCommand) run(cmd *cobra.Command, args []string) err
} else {
name := args[0]
namespacedName := types.NamespacedName{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
err = kubeClient.Get(ctx, namespacedName, export.object.asClientObject())

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
package main

View File

@@ -135,14 +135,14 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
var listOpts []client.ListOption
if !getArgs.allNamespaces {
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace))
listOpts = append(listOpts, client.InNamespace(*kubeconfigArgs.Namespace))
}
if len(args) > 0 {
@@ -162,7 +162,7 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error {
if get.list.len() == 0 {
if !getAll {
logger.Failuref("no %s objects found in %s namespace", get.kind, rootArgs.namespace)
logger.Failuref("no %s objects found in %s namespace", get.kind, *kubeconfigArgs.Namespace)
}
return nil
}

View File

@@ -1,3 +1,4 @@
//go:build e2e
// +build e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build e2e
// +build e2e
package main

View File

@@ -131,7 +131,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
logger.Generatef("generating manifests")
}
tmpDir, err := os.MkdirTemp("", rootArgs.namespace)
tmpDir, err := os.MkdirTemp("", *kubeconfigArgs.Namespace)
if err != nil {
return err
}
@@ -148,7 +148,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
opts := install.Options{
BaseURL: installArgs.manifestsPath,
Version: installArgs.version,
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Components: components,
Registry: installArgs.registry,
ImagePullSecret: installArgs.imagePullSecret,
@@ -156,7 +156,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
NetworkPolicy: installArgs.networkPolicy,
LogLevel: installArgs.logLevel.String(),
NotificationController: rootArgs.defaults.NotificationController,
ManifestFile: fmt.Sprintf("%s.yaml", rootArgs.namespace),
ManifestFile: fmt.Sprintf("%s.yaml", *kubeconfigArgs.Namespace),
Timeout: rootArgs.timeout,
ClusterDomain: installArgs.clusterDomain,
TolerationKeys: installArgs.tolerationKeys,
@@ -183,21 +183,21 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
}
logger.Successf("manifests build completed")
logger.Actionf("installing components in %s namespace", rootArgs.namespace)
logger.Actionf("installing components in %s namespace", *kubeconfigArgs.Namespace)
if installArgs.dryRun {
logger.Successf("install dry-run finished")
return nil
}
applyOutput, err := utils.Apply(ctx, rootArgs.kubeconfig, rootArgs.kubecontext, filepath.Join(tmpDir, manifest.Path))
applyOutput, err := utils.Apply(ctx, kubeconfigArgs, filepath.Join(tmpDir, manifest.Path))
if err != nil {
return fmt.Errorf("install failed: %w", err)
}
fmt.Fprintln(os.Stderr, applyOutput)
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeConfig, err := utils.KubeConfig(kubeconfigArgs)
if err != nil {
return fmt.Errorf("install failed: %w", err)
}

View File

@@ -1,3 +1,4 @@
//go:build e2e
// +build e2e
/*

View File

@@ -99,7 +99,7 @@ func logsCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
cfg, err := utils.KubeConfig(kubeconfigArgs)
if err != nil {
return err
}
@@ -278,7 +278,7 @@ func filterPrintLog(t *template.Template, l *ControllerLogEntry) {
if logsArgs.logLevel != "" && logsArgs.logLevel != l.Level ||
logsArgs.kind != "" && strings.ToLower(logsArgs.kind) != strings.ToLower(l.Kind) ||
logsArgs.name != "" && strings.ToLower(logsArgs.name) != strings.ToLower(l.Name) ||
!logsArgs.allNamespaces && strings.ToLower(rootArgs.namespace) != strings.ToLower(l.Namespace) {
!logsArgs.allNamespaces && strings.ToLower(*kubeconfigArgs.Namespace) != strings.ToLower(l.Namespace) {
return
}

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
/*

View File

@@ -21,13 +21,13 @@ import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"time"
"github.com/spf13/cobra"
"golang.org/x/term"
corev1 "k8s.io/api/core/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"github.com/fluxcd/flux2/pkg/manifestgen/install"
@@ -99,9 +99,6 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.`,
var logger = stderrLogger{stderr: os.Stderr}
type rootFlags struct {
kubeconfig string
kubecontext string
namespace string
timeout time.Duration
verbose bool
pollInterval time.Duration
@@ -109,19 +106,26 @@ type rootFlags struct {
}
var rootArgs = NewRootFlags()
var kubeconfigArgs = genericclioptions.NewConfigFlags(false)
func init() {
rootCmd.PersistentFlags().StringVarP(&rootArgs.namespace, "namespace", "n", rootArgs.defaults.Namespace,
"the namespace scope for this operation, can be set with FLUX_SYSTEM_NAMESPACE env var")
rootCmd.RegisterFlagCompletionFunc("namespace", resourceNamesCompletionFunc(corev1.SchemeGroupVersion.WithKind("Namespace")))
rootCmd.PersistentFlags().DurationVar(&rootArgs.timeout, "timeout", 5*time.Minute, "timeout for this operation")
rootCmd.PersistentFlags().BoolVar(&rootArgs.verbose, "verbose", false, "print generated objects")
rootCmd.PersistentFlags().StringVarP(&rootArgs.kubeconfig, "kubeconfig", "", "",
"absolute path to the kubeconfig file")
rootCmd.PersistentFlags().StringVarP(&rootArgs.kubecontext, "context", "", "", "kubernetes context to use")
configureDefaultNamespace()
kubeconfigArgs.APIServer = nil // prevent AddFlags from configuring --server flag
kubeconfigArgs.Timeout = nil // prevent AddFlags from configuring --request-timeout flag, we have --timeout instead
kubeconfigArgs.AddFlags(rootCmd.PersistentFlags())
// Since some subcommands use the `-s` flag as a short version for `--silent`, we manually configure the server flag
// without the `-s` short version. While we're no longer on par with kubectl's flags, we maintain backwards compatibility
// on the CLI interface.
apiServer := ""
kubeconfigArgs.APIServer = &apiServer
rootCmd.PersistentFlags().StringVar(kubeconfigArgs.APIServer, "server", *kubeconfigArgs.APIServer, "The address and port of the Kubernetes API server")
rootCmd.RegisterFlagCompletionFunc("context", contextsCompletionFunc)
rootCmd.RegisterFlagCompletionFunc("namespace", resourceNamesCompletionFunc(corev1.SchemeGroupVersion.WithKind("Namespace")))
rootCmd.DisableAutoGenTag = true
rootCmd.SetOut(os.Stdout)
@@ -138,30 +142,17 @@ func NewRootFlags() rootFlags {
func main() {
log.SetFlags(0)
configureKubeconfig()
configureDefaultNamespace()
if err := rootCmd.Execute(); err != nil {
logger.Failuref("%v", err)
os.Exit(1)
}
}
func configureKubeconfig() {
switch {
case len(rootArgs.kubeconfig) > 0:
case len(os.Getenv("KUBECONFIG")) > 0:
rootArgs.kubeconfig = os.Getenv("KUBECONFIG")
default:
if home := homeDir(); len(home) > 0 {
rootArgs.kubeconfig = filepath.Join(home, ".kube", "config")
}
}
}
func configureDefaultNamespace() {
*kubeconfigArgs.Namespace = rootArgs.defaults.Namespace
fromEnv := os.Getenv("FLUX_SYSTEM_NAMESPACE")
if fromEnv != "" && rootArgs.namespace == rootArgs.defaults.Namespace {
rootArgs.namespace = fromEnv
if fromEnv != "" {
kubeconfigArgs.Namespace = &fromEnv
}
}

View File

@@ -1,3 +1,4 @@
//go:build e2e
// +build e2e
/*
@@ -35,7 +36,7 @@ func TestMain(m *testing.M) {
if err != nil {
panic(fmt.Errorf("error creating kube manager: '%w'", err))
}
rootArgs.kubeconfig = testEnv.kubeConfigPath
kubeconfigArgs.KubeConfig = &testEnv.kubeConfigPath
// Install Flux.
output, err := executeCommand("install --components-extra=image-reflector-controller,image-automation-controller")
@@ -54,7 +55,7 @@ func TestMain(m *testing.M) {
// Delete namespace and wait for finalisation
kubectlArgs := []string{"delete", "namespace", "flux-system"}
_, err = utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...)
_, err = utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, kubectlArgs...)
if err != nil {
panic(fmt.Errorf("delete namespace error:'%w'", err))
}
@@ -66,13 +67,13 @@ func TestMain(m *testing.M) {
func setupTestNamespace(namespace string) (func(), error) {
kubectlArgs := []string{"create", "namespace", namespace}
_, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...)
_, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, kubectlArgs...)
if err != nil {
return nil, err
}
return func() {
kubectlArgs := []string{"delete", "namespace", namespace}
utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...)
utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, kubectlArgs...)
}, nil
}

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
/*
@@ -42,7 +43,8 @@ func TestMain(m *testing.M) {
panic(fmt.Errorf("error creating kube manager: '%w'", err))
}
testEnv = km
rootArgs.kubeconfig = testEnv.kubeConfigPath
// rootArgs.kubeconfig = testEnv.kubeConfigPath
kubeconfigArgs.KubeConfig = &testEnv.kubeConfigPath
// Run tests
code := m.Run()

View File

@@ -75,13 +75,13 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
namespacedName := types.NamespacedName{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
@@ -94,7 +94,7 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error {
return fmt.Errorf("resource is suspended")
}
logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, rootArgs.namespace)
logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, *kubeconfigArgs.Namespace)
if err := requestReconciliation(ctx, kubeClient, namespacedName, reconcile.object); err != nil {
return err
}

View File

@@ -54,17 +54,17 @@ func reconcileAlertProviderCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
namespacedName := types.NamespacedName{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
logger.Actionf("annotating Provider %s in %s namespace", name, rootArgs.namespace)
logger.Actionf("annotating Provider %s in %s namespace", name, *kubeconfigArgs.Namespace)
var alertProvider notificationv1.Provider
err = kubeClient.Get(ctx, namespacedName, &alertProvider)
if err != nil {

View File

@@ -54,13 +54,13 @@ func reconcileReceiverCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
namespacedName := types.NamespacedName{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
@@ -74,7 +74,7 @@ func reconcileReceiverCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("resource is suspended")
}
logger.Actionf("annotating Receiver %s in %s namespace", name, rootArgs.namespace)
logger.Actionf("annotating Receiver %s in %s namespace", name, *kubeconfigArgs.Namespace)
if receiver.Annotations == nil {
receiver.Annotations = map[string]string{
meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano),

View File

@@ -36,13 +36,13 @@ func (reconcile reconcileWithSourceCommand) run(cmd *cobra.Command, args []strin
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
namespacedName := types.NamespacedName{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}
@@ -57,20 +57,20 @@ func (reconcile reconcileWithSourceCommand) run(cmd *cobra.Command, args []strin
if reconcile.object.reconcileSource() {
reconcileCmd, nsName := reconcile.object.getSource()
nsCopy := rootArgs.namespace
nsCopy := *kubeconfigArgs.Namespace
if nsName.Namespace != "" {
rootArgs.namespace = nsName.Namespace
*kubeconfigArgs.Namespace = nsName.Namespace
}
err := reconcileCmd.run(nil, []string{nsName.Name})
if err != nil {
return err
}
rootArgs.namespace = nsCopy
*kubeconfigArgs.Namespace = nsCopy
}
lastHandledReconcileAt := reconcile.object.lastHandledReconcileRequest()
logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, rootArgs.namespace)
logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, *kubeconfigArgs.Namespace)
if err := requestReconciliation(ctx, kubeClient, namespacedName, reconcile.object); err != nil {
return err
}

View File

@@ -72,13 +72,13 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
var listOpts []client.ListOption
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace))
listOpts = append(listOpts, client.InNamespace(*kubeconfigArgs.Namespace))
if len(args) > 0 {
listOpts = append(listOpts, client.MatchingFields{
"metadata.name": args[0],
@@ -91,12 +91,12 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error {
}
if resume.list.len() == 0 {
logger.Failuref("no %s objects found in %s namespace", resume.kind, rootArgs.namespace)
logger.Failuref("no %s objects found in %s namespace", resume.kind, *kubeconfigArgs.Namespace)
return nil
}
for i := 0; i < resume.list.len(); i++ {
logger.Actionf("resuming %s %s in %s namespace", resume.humanKind, resume.list.resumeItem(i).asClientObject().GetName(), rootArgs.namespace)
logger.Actionf("resuming %s %s in %s namespace", resume.humanKind, resume.list.resumeItem(i).asClientObject().GetName(), *kubeconfigArgs.Namespace)
resume.list.resumeItem(i).setUnsuspended()
if err := kubeClient.Update(ctx, resume.list.resumeItem(i).asClientObject()); err != nil {
return err
@@ -105,7 +105,7 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error {
namespacedName := types.NamespacedName{
Name: resume.list.resumeItem(i).asClientObject().GetName(),
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
}
logger.Waitingf("waiting for %s reconciliation", resume.kind)

View File

@@ -69,11 +69,11 @@ func isReady(ctx context.Context, kubeClient client.Client,
func buildComponentObjectRefs(components ...string) ([]object.ObjMetadata, error) {
var objRefs []object.ObjMetadata
for _, deployment := range components {
objMeta, err := object.CreateObjMetadata(rootArgs.namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"})
if err != nil {
return nil, err
}
objRefs = append(objRefs, objMeta)
objRefs = append(objRefs, object.ObjMetadata{
Namespace: *kubeconfigArgs.Namespace,
Name: deployment,
GroupKind: schema.GroupKind{Group: "apps", Kind: "Deployment"},
})
}
return objRefs, nil
}

View File

@@ -69,13 +69,13 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
var listOpts []client.ListOption
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace))
listOpts = append(listOpts, client.InNamespace(*kubeconfigArgs.Namespace))
if len(args) > 0 {
listOpts = append(listOpts, client.MatchingFields{
"metadata.name": args[0],
@@ -88,12 +88,12 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error {
}
if suspend.list.len() == 0 {
logger.Failuref("no %s objects found in %s namespace", suspend.kind, rootArgs.namespace)
logger.Failuref("no %s objects found in %s namespace", suspend.kind, *kubeconfigArgs.Namespace)
return nil
}
for i := 0; i < suspend.list.len(); i++ {
logger.Actionf("suspending %s %s in %s namespace", suspend.humanKind, suspend.list.item(i).asClientObject().GetName(), rootArgs.namespace)
logger.Actionf("suspending %s %s in %s namespace", suspend.humanKind, suspend.list.item(i).asClientObject().GetName(), *kubeconfigArgs.Namespace)
suspend.list.item(i).setSuspended()
if err := kubeClient.Update(ctx, suspend.list.item(i).asClientObject()); err != nil {
return err

View File

@@ -27,8 +27,10 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/cli-runtime/pkg/resource"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/flux2/internal/utils"
@@ -39,20 +41,26 @@ import (
)
var traceCmd = &cobra.Command{
Use: "trace [name]",
Short: "Trace an in-cluster object throughout the GitOps delivery pipeline",
Long: `The trace command shows how an object is managed by Flux,
from which source and revision it comes, and what's the latest reconciliation status.'`,
Example: ` # Trace a Kubernetes Deployment
flux trace my-app --kind=deployment --api-version=apps/v1 --namespace=apps
Use: "trace <resource> <name> [<name> ...]",
Short: "Trace in-cluster objects throughout the GitOps delivery pipeline",
Long: `The trace command shows how one or more objects are managed by Flux,
from which source and revision they come, and what the latest reconciliation status is.
# Trace a Kubernetes Pod
flux trace redis-master-0 --kind=pod --api-version=v1 -n redis
You can also trace multiple objects with different resource kinds using <resource>/<name> multiple times.`,
Example: ` # Trace a Kubernetes Deployment
flux trace -n apps deployment my-app
# Trace a Kubernetes Pod and a config map
flux trace -n redis pod/redis-master-0 cm/redis
# Trace a Kubernetes global object
flux trace redis --kind=namespace --api-version=v1
flux trace namespace redis
# Trace a Kubernetes custom resource
flux trace -n redis helmrelease redis
# API Version and Kind can also be specified explicitly
# Note that either both, kind and api-version, or neither have to be specified.
flux trace redis --kind=helmrelease --api-version=helm.toolkit.fluxcd.io/v2beta1 -n redis`,
RunE: traceCmdRun,
}
@@ -73,49 +81,43 @@ func init() {
}
func traceCmdRun(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("object name is required")
}
name := args[0]
if traceArgs.kind == "" {
return fmt.Errorf("object kind is required (--kind)")
}
if traceArgs.apiVersion == "" {
return fmt.Errorf("object apiVersion is required (--api-version)")
}
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
gv, err := schema.ParseGroupVersion(traceArgs.apiVersion)
var objects []*unstructured.Unstructured
if traceArgs.kind != "" || traceArgs.apiVersion != "" {
var obj *unstructured.Unstructured
obj, err = getObjectStatic(ctx, kubeClient, args)
objects = []*unstructured.Unstructured{obj}
} else {
objects, err = getObjectDynamic(args)
}
if err != nil {
return fmt.Errorf("invaild apiVersion: %w", err)
return err
}
obj := &unstructured.Unstructured{}
obj.SetGroupVersionKind(schema.GroupVersionKind{
Group: gv.Group,
Version: gv.Version,
Kind: traceArgs.kind,
})
return traceObjects(ctx, kubeClient, objects)
}
objName := types.NamespacedName{
Namespace: rootArgs.namespace,
Name: name,
}
err = kubeClient.Get(ctx, objName, obj)
if err != nil {
return fmt.Errorf("failed to find object: %w", err)
func traceObjects(ctx context.Context, kubeClient client.Client, objects []*unstructured.Unstructured) error {
for i, obj := range objects {
err := traceObject(ctx, kubeClient, obj)
if err != nil {
rootCmd.PrintErrf("failed to trace %v/%v in namespace %v: %v", obj.GetKind(), obj.GetName(), obj.GetNamespace(), err)
}
if i < len(objects)-1 {
rootCmd.Println("---")
}
}
return nil
}
func traceObject(ctx context.Context, kubeClient client.Client, obj *unstructured.Unstructured) error {
if ks, ok := isOwnerManagedByFlux(ctx, kubeClient, obj, kustomizev1.GroupVersion.Group); ok {
report, err := traceKustomization(ctx, kubeClient, ks, obj)
if err != nil {
@@ -137,14 +139,85 @@ func traceCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("object not managed by Flux")
}
func getObjectStatic(ctx context.Context, kubeClient client.Client, args []string) (*unstructured.Unstructured, error) {
if len(args) < 1 {
return nil, fmt.Errorf("object name is required")
}
if traceArgs.kind == "" {
return nil, fmt.Errorf("object kind is required (--kind)")
}
if traceArgs.apiVersion == "" {
return nil, fmt.Errorf("object apiVersion is required (--api-version)")
}
gv, err := schema.ParseGroupVersion(traceArgs.apiVersion)
if err != nil {
return nil, fmt.Errorf("invaild apiVersion: %w", err)
}
obj := &unstructured.Unstructured{}
obj.SetGroupVersionKind(schema.GroupVersionKind{
Group: gv.Group,
Version: gv.Version,
Kind: traceArgs.kind,
})
objName := types.NamespacedName{
Namespace: *kubeconfigArgs.Namespace,
Name: args[0],
}
if err = kubeClient.Get(ctx, objName, obj); err != nil {
return nil, fmt.Errorf("failed to find object: %w", err)
}
return obj, nil
}
func getObjectDynamic(args []string) ([]*unstructured.Unstructured, error) {
r := resource.NewBuilder(kubeconfigArgs).
Unstructured().
NamespaceParam(*kubeconfigArgs.Namespace).DefaultNamespace().
ResourceTypeOrNameArgs(false, args...).
ContinueOnError().
Latest().
Do()
if err := r.Err(); err != nil {
if resource.IsUsageError(err) {
return nil, fmt.Errorf("either `<resource>/<name>` or `<resource> <name>` is required as an argument")
}
return nil, err
}
infos, err := r.Infos()
if err != nil {
return nil, fmt.Errorf("x: %v", err)
}
if len(infos) == 0 {
return nil, fmt.Errorf("failed to find object: %w", err)
}
objects := []*unstructured.Unstructured{}
for _, info := range infos {
obj := &unstructured.Unstructured{}
obj.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(info.Object)
if err != nil {
return objects, err
}
objects = append(objects, obj)
}
return objects, nil
}
func traceKustomization(ctx context.Context, kubeClient client.Client, ksName types.NamespacedName, obj *unstructured.Unstructured) (string, error) {
ks := &kustomizev1.Kustomization{}
ksReady := &metav1.Condition{}
err := kubeClient.Get(ctx, ksName, ks)
if err != nil {
return "", fmt.Errorf("failed to find kustomization: %w", err)
}
ksReady = meta.FindStatusCondition(ks.Status.Conditions, fluxmeta.ReadyCondition)
ksReady := meta.FindStatusCondition(ks.Status.Conditions, fluxmeta.ReadyCondition)
var ksRepository *sourcev1.GitRepository
var ksRepositoryReady *metav1.Condition
@@ -252,12 +325,11 @@ Status: Unknown
func traceHelm(ctx context.Context, kubeClient client.Client, hrName types.NamespacedName, obj *unstructured.Unstructured) (string, error) {
hr := &helmv2.HelmRelease{}
hrReady := &metav1.Condition{}
err := kubeClient.Get(ctx, hrName, hr)
if err != nil {
return "", fmt.Errorf("failed to find HelmRelease: %w", err)
}
hrReady = meta.FindStatusCondition(hr.Status.Conditions, fluxmeta.ReadyCondition)
hrReady := meta.FindStatusCondition(hr.Status.Conditions, fluxmeta.ReadyCondition)
var hrChart *sourcev1.HelmChart
var hrChartReady *metav1.Condition

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
package main
@@ -9,7 +10,7 @@ import (
func TestTraceNoArgs(t *testing.T) {
cmd := cmdTestCase{
args: "trace",
assert: assertError("object name is required"),
assert: assertError("either `<resource>/<name>` or `<resource> <name>` is required as an argument"),
}
cmd.runTestCmd(t)
}

View File

@@ -77,27 +77,26 @@ func treeKsCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
k := &kustomizev1.Kustomization{}
err = kubeClient.Get(ctx, client.ObjectKey{
Namespace: rootArgs.namespace,
Namespace: *kubeconfigArgs.Namespace,
Name: name,
}, k)
if err != nil {
return err
}
kMeta, err := object.CreateObjMetadata(k.Namespace, k.Name,
schema.GroupKind{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind})
if err != nil {
return err
}
kTree := tree.New(object.ObjMetadata{
Namespace: k.Namespace,
Name: k.Name,
GroupKind: schema.GroupKind{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind},
})
kTree := tree.New(kMeta)
err = treeKustomization(ctx, kTree, k, kubeClient, treeKsArgs.compact)
if err != nil {
return err
@@ -273,5 +272,5 @@ func getHelmReleaseInventory(ctx context.Context, objectKey client.ObjectKey, ku
return nil, fmt.Errorf("failed to read the Helm storage object for HelmRelease '%s': %w", objectKey.String(), err)
}
return object.UnstructuredsToObjMetas(objects)
return object.UnstructuredSetToObjMetadataSet(objects), nil
}

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
/*

View File

@@ -82,13 +82,13 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
logger.Actionf("deleting components in %s namespace", rootArgs.namespace)
uninstallComponents(ctx, kubeClient, rootArgs.namespace, uninstallArgs.dryRun)
logger.Actionf("deleting components in %s namespace", *kubeconfigArgs.Namespace)
uninstallComponents(ctx, kubeClient, *kubeconfigArgs.Namespace, uninstallArgs.dryRun)
logger.Actionf("deleting toolkit.fluxcd.io finalizers in all namespaces")
uninstallFinalizers(ctx, kubeClient, uninstallArgs.dryRun)
@@ -97,7 +97,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
uninstallCustomResourceDefinitions(ctx, kubeClient, uninstallArgs.dryRun)
if !uninstallArgs.keepNamespace {
uninstallNamespace(ctx, kubeClient, rootArgs.namespace, uninstallArgs.dryRun)
uninstallNamespace(ctx, kubeClient, *kubeconfigArgs.Namespace, uninstallArgs.dryRun)
}
logger.Successf("uninstall finished")

View File

@@ -74,19 +74,19 @@ func versionCmdRun(cmd *cobra.Command, args []string) error {
info["flux"] = rootArgs.defaults.Version
if !versionArgs.client {
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
kubeClient, err := utils.KubeClient(kubeconfigArgs)
if err != nil {
return err
}
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
var list v1.DeploymentList
if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err != nil {
if err := kubeClient.List(ctx, &list, client.InNamespace(*kubeconfigArgs.Namespace), selector); err != nil {
return err
}
if len(list.Items) == 0 {
return fmt.Errorf("no deployments found in %s namespace", rootArgs.namespace)
return fmt.Errorf("no deployments found in %s namespace", *kubeconfigArgs.Namespace)
}
for _, d := range list.Items {

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
/*

148
go.mod
View File

@@ -1,42 +1,140 @@
module github.com/fluxcd/flux2
go 1.16
go 1.17
require (
github.com/Masterminds/semver/v3 v3.1.0
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7
github.com/ProtonMail/go-crypto v0.0.0-20211221144345-a4f6767435ab
github.com/cyphar/filepath-securejoin v0.2.2
github.com/fluxcd/go-git-providers v0.4.0
github.com/fluxcd/helm-controller/api v0.14.1
github.com/fluxcd/image-automation-controller/api v0.18.0
github.com/fluxcd/image-reflector-controller/api v0.14.0
github.com/fluxcd/kustomize-controller/api v0.18.2
github.com/fluxcd/notification-controller/api v0.19.0
github.com/fluxcd/pkg/apis/meta v0.10.1
github.com/fluxcd/pkg/runtime v0.12.2
github.com/fluxcd/pkg/ssa v0.3.1
github.com/fluxcd/pkg/ssh v0.0.5
github.com/fluxcd/go-git-providers v0.5.2
github.com/fluxcd/helm-controller/api v0.15.0
github.com/fluxcd/image-automation-controller/api v0.19.0
github.com/fluxcd/image-reflector-controller/api v0.15.0
github.com/fluxcd/kustomize-controller/api v0.19.1
github.com/fluxcd/notification-controller/api v0.20.1
github.com/fluxcd/pkg/apis/meta v0.10.2
github.com/fluxcd/pkg/runtime v0.12.3
github.com/fluxcd/pkg/ssa v0.10.0
github.com/fluxcd/pkg/ssh v0.3.1
github.com/fluxcd/pkg/untar v0.0.5
github.com/fluxcd/pkg/version v0.0.1
github.com/fluxcd/source-controller/api v0.19.2
github.com/go-errors/errors v1.4.0 // indirect
github.com/fluxcd/source-controller/api v0.20.1
github.com/go-git/go-git/v5 v5.4.2
github.com/google/go-cmp v0.5.6
github.com/google/go-containerregistry v0.2.0
github.com/manifoldco/promptui v0.9.0
github.com/mattn/go-shellwords v1.0.12
github.com/olekukonko/tablewriter v0.0.4
github.com/spf13/cobra v1.1.3
github.com/spf13/cobra v1.2.1
github.com/spf13/pflag v1.0.5
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d
k8s.io/api v0.22.2
k8s.io/apiextensions-apiserver v0.22.2
k8s.io/apimachinery v0.22.2
k8s.io/client-go v0.22.2
k8s.io/kubectl v0.21.1
sigs.k8s.io/cli-utils v0.26.0
sigs.k8s.io/controller-runtime v0.10.2
sigs.k8s.io/kustomize/api v0.8.10
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
k8s.io/api v0.23.1
k8s.io/apiextensions-apiserver v0.23.1
k8s.io/apimachinery v0.23.1
k8s.io/cli-runtime v0.23.1
k8s.io/client-go v0.23.1
k8s.io/kubectl v0.23.1
sigs.k8s.io/cli-utils v0.27.0
sigs.k8s.io/controller-runtime v0.11.0
sigs.k8s.io/kustomize/api v0.10.1
sigs.k8s.io/yaml v1.3.0
)
require (
cloud.google.com/go v0.81.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
github.com/Microsoft/go-winio v0.4.16 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fluxcd/pkg/apis/acl v0.0.3 // indirect
github.com/fluxcd/pkg/apis/kustomize v0.3.1 // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/go-billy/v5 v5.3.1 // indirect
github.com/go-logr/logr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/go-github/v41 v41.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-runewidth v0.0.7 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday v1.5.2 // indirect
github.com/russross/blackfriday/v2 v2.0.1 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/stretchr/testify v1.7.0 // indirect
github.com/xanzy/go-gitlab v0.54.3 // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/component-base v0.23.1 // indirect
k8s.io/klog/v2 v2.30.0 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
k8s.io/utils v0.0.0-20211208161948-7d6a63dca704 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
)
// Fix for CVE-2020-29652: https://github.com/golang/crypto/commit/8b5274cf687fd9316b4108863654cc57385531e8
// Fix for CVE-2021-43565: https://github.com/golang/crypto/commit/5770296d904e90f15f38f77dfc2e43fdf5efc083
replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3

605
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,7 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/cli-runtime/pkg/genericclioptions"
"sigs.k8s.io/cli-utils/pkg/object"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/kustomize/api/filesys"
@@ -57,8 +58,7 @@ type PlainGitBootstrapper struct {
gpgPassphrase string
gpgKeyID string
kubeconfig string
kubecontext string
restClientGetter genericclioptions.RESTClientGetter
postGenerateSecret []PostGenerateSecretFunc
@@ -167,12 +167,12 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest
if _, err := os.Stat(kfile); err == nil {
// Apply the components and their patches
b.logger.Actionf("installing components in %q namespace", options.Namespace)
if _, err := utils.Apply(ctx, b.kubeconfig, b.kubecontext, kfile); err != nil {
if _, err := utils.Apply(ctx, b.restClientGetter, kfile); err != nil {
return err
}
} else {
// Apply the CRDs and controllers
if _, err := utils.Apply(ctx, b.kubeconfig, b.kubecontext, componentsYAML); err != nil {
if _, err := utils.Apply(ctx, b.restClientGetter, componentsYAML); err != nil {
return err
}
}
@@ -299,7 +299,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options
// Apply to cluster
b.logger.Actionf("applying sync manifests")
if _, err := utils.Apply(ctx, b.kubeconfig, b.kubecontext, filepath.Join(b.git.Path(), kusManifests.Path)); err != nil {
if _, err := utils.Apply(ctx, b.restClientGetter, filepath.Join(b.git.Path(), kusManifests.Path)); err != nil {
return err
}
@@ -332,7 +332,7 @@ func (b *PlainGitBootstrapper) ReportKustomizationHealth(ctx context.Context, op
}
func (b *PlainGitBootstrapper) ReportComponentsHealth(ctx context.Context, install install.Options, timeout time.Duration) error {
cfg, err := utils.KubeConfig(b.kubeconfig, b.kubecontext)
cfg, err := utils.KubeConfig(b.restClientGetter)
if err != nil {
return err
}

View File

@@ -200,8 +200,10 @@ func (b *GitProviderBootstrapper) ReconcileSyncConfig(ctx context.Context, optio
if err != nil {
return err
}
options.URL = syncURL
}
return b.PlainGitBootstrapper.ReconcileSyncConfig(ctx, options)
}
@@ -414,14 +416,11 @@ func (b *GitProviderBootstrapper) getOrganization(ctx context.Context, subOrgs [
func (b *GitProviderBootstrapper) getCloneURL(repository gitprovider.UserRepository, transport gitprovider.TransportType) (string, error) {
var url string
if cloner, ok := repository.(gitprovider.CloneableURL); ok {
return cloner.GetCloneURL("", transport), nil
url = cloner.GetCloneURL("", transport)
} else {
url = repository.Repository().GetCloneURL(transport)
}
url = repository.Repository().GetCloneURL(transport)
// TODO(hidde): https://github.com/fluxcd/go-git-providers/issues/55
if strings.HasPrefix(url, "https://https://") {
url = strings.TrimPrefix(url, "https://")
}
var err error
if transport == gitprovider.TransportTypeSSH && b.sshHostname != "" {
if url, err = setHostname(url, b.sshHostname); err != nil {

View File

@@ -1,3 +1,4 @@
//go:build unit
// +build unit
package gogit

View File

@@ -19,6 +19,7 @@ package bootstrap
import (
"github.com/fluxcd/flux2/internal/bootstrap/git"
"github.com/fluxcd/flux2/pkg/log"
"k8s.io/cli-runtime/pkg/genericclioptions"
)
type Option interface {
@@ -90,21 +91,18 @@ func (o commitMessageAppendixOption) applyGitProvider(b *GitProviderBootstrapper
o.applyGit(b.PlainGitBootstrapper)
}
func WithKubeconfig(kubeconfig, kubecontext string) Option {
func WithKubeconfig(rcg genericclioptions.RESTClientGetter) Option {
return kubeconfigOption{
kubeconfig: kubeconfig,
kubecontext: kubecontext,
rcg: rcg,
}
}
type kubeconfigOption struct {
kubeconfig string
kubecontext string
rcg genericclioptions.RESTClientGetter
}
func (o kubeconfigOption) applyGit(b *PlainGitBootstrapper) {
b.kubeconfig = o.kubeconfig
b.kubecontext = o.kubecontext
b.restClientGetter = o.rcg
}
func (o kubeconfigOption) applyGitProvider(b *GitProviderBootstrapper) {

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -26,9 +26,9 @@ import (
"github.com/fluxcd/pkg/ssa"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/cli-runtime/pkg/genericclioptions"
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/kustomize/api/konfig"
"github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
@@ -36,12 +36,12 @@ import (
// Apply is the equivalent of 'kubectl apply --server-side -f'.
// If the given manifest is a kustomization.yaml, then apply performs the equivalent of 'kubectl apply --server-side -k'.
func Apply(ctx context.Context, kubeConfigPath string, kubeContext string, manifestPath string) (string, error) {
cfg, err := KubeConfig(kubeConfigPath, kubeContext)
func Apply(ctx context.Context, rcg genericclioptions.RESTClientGetter, manifestPath string) (string, error) {
cfg, err := KubeConfig(rcg)
if err != nil {
return "", err
}
restMapper, err := apiutil.NewDynamicRESTMapper(cfg)
restMapper, err := rcg.ToRESTMapper()
if err != nil {
return "", err
}
@@ -49,7 +49,7 @@ func Apply(ctx context.Context, kubeConfigPath string, kubeContext string, manif
if err != nil {
return "", err
}
kubePoller := polling.NewStatusPoller(kubeClient, restMapper)
kubePoller := polling.NewStatusPoller(kubeClient, restMapper, nil)
resourceManager := ssa.NewResourceManager(kubeClient, kubePoller, ssa.Owner{
Field: "flux",

View File

@@ -37,8 +37,8 @@ import (
apiruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
sigyaml "k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
@@ -107,22 +107,8 @@ func ExecKubectlCommand(ctx context.Context, mode ExecMode, kubeConfigPath strin
return "", nil
}
func ClientConfig(kubeConfigPath string, kubeContext string) clientcmd.ClientConfig {
configFiles := SplitKubeConfigPath(kubeConfigPath)
configOverrides := clientcmd.ConfigOverrides{}
if len(kubeContext) > 0 {
configOverrides.CurrentContext = kubeContext
}
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{Precedence: configFiles},
&configOverrides,
)
}
func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error) {
cfg, err := ClientConfig(kubeConfigPath, kubeContext).ClientConfig()
func KubeConfig(rcg genericclioptions.RESTClientGetter) (*rest.Config, error) {
cfg, err := rcg.ToRESTConfig()
if err != nil {
return nil, fmt.Errorf("kubernetes configuration load failed: %w", err)
}
@@ -152,10 +138,10 @@ func NewScheme() *apiruntime.Scheme {
return scheme
}
func KubeClient(kubeConfigPath string, kubeContext string) (client.WithWatch, error) {
cfg, err := KubeConfig(kubeConfigPath, kubeContext)
func KubeClient(rcg genericclioptions.RESTClientGetter) (client.WithWatch, error) {
cfg, err := rcg.ToRESTConfig()
if err != nil {
return nil, fmt.Errorf("kubernetes client initialization failed: %w", err)
return nil, err
}
scheme := NewScheme()

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/helm-controller/releases/download/v0.14.1/helm-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.14.1/helm-controller.deployment.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.15.0/helm-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.15.0/helm-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.18.0/image-automation-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.18.0/image-automation-controller.deployment.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.19.0/image-automation-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.19.0/image-automation-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.14.0/image-reflector-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.14.0/image-reflector-controller.deployment.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.15.0/image-reflector-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.15.0/image-reflector-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.18.2/kustomize-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.18.2/kustomize-controller.deployment.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.19.1/kustomize-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.19.1/kustomize-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/notification-controller/releases/download/v0.19.0/notification-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v0.19.0/notification-controller.deployment.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v0.20.1/notification-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v0.20.1/notification-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/source-controller/releases/download/v0.19.2/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.19.2/source-controller.deployment.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.20.1/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.20.1/source-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,9 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/source-controller/releases/download/v0.19.2/source-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.18.2/kustomize-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.14.1/helm-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v0.19.0/notification-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.14.0/image-reflector-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.18.0/image-automation-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.20.1/source-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.19.1/kustomize-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.15.0/helm-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v0.20.1/notification-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.15.0/image-reflector-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.19.0/image-automation-controller.crds.yaml

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -1,3 +1,4 @@
//go:build !e2e
// +build !e2e
/*

View File

@@ -58,7 +58,7 @@ func NewStatusChecker(kubeConfig *rest.Config, pollInterval time.Duration, timeo
pollInterval: pollInterval,
timeout: timeout,
client: c,
statusPoller: polling.NewStatusPoller(c, restMapper),
statusPoller: polling.NewStatusPoller(c, restMapper, nil),
logger: log,
}, nil
}

View File

@@ -0,0 +1,166 @@
# RFC-0001 Memorandum on Flux Authorization
## Summary
This RFC describes in detail, for [Flux version 0.24][] (Nov 2021), how Flux determines which
operations are allowed to proceed, and how this interacts with Kubernetes' access control.
## Motivation
To this point, the Flux project has provided [examples of how to make a multi-tenant
system](https://github.com/fluxcd/flux2-multi-tenancy/tree/v0.1.0), but not explained exactly how
they relate to Flux's authorization model; nor has the authorization model itself been
documented. Further work on support for multi-tenancy, among other things, requires a full account
of Flux's authorization model as a baseline.
### Goals
- Give a comprehensive account of Flux's authorization model
### Non-Goals
- Justify the model as it stands; this RFC simply records the state as at v0.24.
## Flux's authorization model
The Flux controllers undertake operations as specified by custom resources of the kinds defined in
the [Flux API][]. Most of the operations are through the Kubernetes API. Authorization for
operations on external systems is not accounted for here.
Flux controllers defer to [Kubernetes' native RBAC][k8s-rbac] and [namespace isolation][k8s-ns] to
determine which operations are authorized, when processing the custom resources in the Flux API.
In general, **Kubernetes API operations are constrained by the service account under which each
controller pod runs**. In the [default deployment of Flux][flux-rbac] each controller has its own
service account; and, the service accounts for the Kustomize controller and Helm controller have the
[`cluster-admin` cluster role][k8s-cluster-admin] bound to it.
Both the Kustomize controller and the Helm controller create, update and delete arbitrary sets of
configuration that they take as user input. For example, a Kustomization object that references a
GitRepository is processed by taking whatever is in the specified Git repository and applying it to
the cluster. This is informally called "syncing", and these user-supplied configurations will be
called "sync configurations" in the following.
There are five types of access that have a distinct treatment with respect to RBAC and namespace
isolation:
- reading and writing the Flux API object to be processed
- accessing dependencies of a Flux API object; for example, a secret that holds a decryption key
- accessing Flux API objects related to the object being processed; for example, a GitRepository
referenced by a Kustomization
- creating, updating and deleting Flux API objects as part of processing; for example, each
`HelmRelease` object contains a template for a Helm chart spec, which the Helm controller uses to
create a `HelmChart` object
- creating, updating, deleting, and health-checking of arbitrary objects as specified by _sync
configurations_ (as mentioned above).
This table summarises how these operations are subject to RBAC and namespace isolation.
| Type of operation | Accessed via | Namespace isolation |
|------------------------------------------------|----------------------------|------------------------------|
| Reading and writing the object to be processed | Controller service account | N/A |
| Dependencies of object to be processed | Controller service account | Same namespace only |
| Access to related Flux API objects | Controller service account | Some cross-namespace refs[1] |
| CRUD of Flux API objects | Controller service account | Created in same namespace |
| CRUD and healthcheck of sync configurations | Impersonation[2] | As directed by spec[2] |
[1] See "Cross-namespace references" below<br>
[2] See "Impersonation" below
There are two related mechanisms that affect the service account used for the operations marked with
"Impersonation" above: "impersonation" and "remote apply". These are explained in the following
sections.
### Impersonation
The Kustomize controller and Helm controller both apply arbitrary sets of Kubernetes configuration
("_synced configuration_" as above) to a cluster. These controllers use the service account named in
the field `.spec.serviceAccountName` in the `Kustomization` and `HelmRelease` objects respectively,
while applying and health-checking the synced configuration. This mechanism is called
"impersonation".
The `.spec.serviceAccountName` field is optional. If empty, the controller's service account is
used.
### Remote apply
The Kustomize controller and Helm controller are able to apply a set of configuration to a cluster
other than the cluster in which they run. If the `Kustomization` or `HelmRelease` object [refers to
a secret containing a "kubeconfig" file][kubeconfig], the controller will construct a client using
that kubeconfig, and the client is used to apply the prepared set of configuration. The effect of
this is that the configuration will be applied as the user given in the kubeconfig; often this is a
user with the `cluster-admin` role bound to it, but not necessarily so.
All accesses that would use impersonation use the remote client instead.
### Cross-namespace references
Some Flux API kinds have fields which can refer to a Flux API object in another namespace. The Flux
controllers do not respect namespace isolation when dereferencing these fields. The following are
fields that are not restricted to the namespace of the containing object, listed by API kind.
| API kind | field | explanation |
|----------|-------|-------------|
| **`kustomizations.kustomize.toolkit.fluxcd.io/v1beta2`** | `.spec.dependsOn` | Items are references that can include a namespace |
| | `.spec.healthChecks` | Items are references that can include a namespace (note: these are accessed using impersonation) |
| | `.spec.sourceRef` | This is a reference that can include a namespace |
| | `.spec.targetNamespace` | This sets or overrides the namespace given in the top-most `kustomization.yaml` |
| **`helmreleases.helm.toolkit.fluxcd/v2beta1`** | `.spec.dependsOn` | Items are references that can include a namespace |
| | `.spec.targetNamespace` | This gives the namespace into which a Helm chart is installed (note: using impersonation) |
| | `.spec.storageNamespace` | This gives the namespace in which the record of a Helm install is created (note: using impersonation) |
| | `.spec.chart.spec.sourceRef` | This is a reference (in the created `HelmChart` object) that can include a namespace |
| **`alerts.notification.toolkit.fluxcd.io/v1beta1`** | `.spec.eventSources` | Items are references that can include a namespace |
| **`receivers.notification.toolkit.fluxcd.io/v1beta1`** | `.spec.resources` | Items in this field are references that can include a namespace |
| **`imagepolicies.image.toolkit.fluxcd.io/v1beta1`** | `.spec.imageRepositoryRef` | This reference can include a namespace[1] |
[1] This particular cross-namespace reference is subject to additional access control; see "Access
control for cross-namespace references" below.
Note that the field `.spec.sourceRef` of **`imageupdateautomation.image.toolkit.fluxcd.io`** does
_not_ include a namespace.
#### Access control for cross-namespace references
In v0.24, an `ImagePolicy` object can refer to a `ImageRepository` object in another
namespace. Unlike most cross-namespace references, the controller processing `ImagePolicy` objects
applies additional access control, as given in the referenced `ImageRepository`: the field
[`.spec.accessFrom`][access-from-ref] grants access to the namespaces selected therein. Access is
denied unless granted.
## Security considerations
### Impersonation is optional
Flux does not insist on a service account to be supplied in `Kustomization` and `HelmRelease`
specifications, and the default is to use the controller's service account. That means a user with
the ability to create either of those objects can trivially arrange for a configuration to be
applied with the controller service account, which in the default deployment of Flux will have
`cluster-admin` bound to it. This represents a privilege escalation vulnerability in the default
deployment of Flux. To guard against it, an admission controller can be used to make the
`.spec.serviceAccountName` field mandatory; an example which uses Kyverno is given in [the
multi-tenancy implementation][multi-tenancy-eg].
### Cross-namespace references side-step namespace isolation
`HelmRelease` and `Kustomization` objects can refer to `GitRepository`, `HelmRepository`, or
`Bucket` (collectively "sources") in any other namespace. The referenced objects are accessed
through the controller's service account, which by default has `cluster-admin` bound to it. This
means all sources in a cluster are by default usable as a synced configuration, from any
namespace. To restrict access, an admission controller can be used to block cross-namespace
references; the [example using Kyverno][multi-tenancy-eg] from above also does this.
## References
- [CVE-2021-41254](https://github.com/fluxcd/kustomize-controller/security/advisories/GHSA-35rf-v2jv-gfg7)
"Privilege escalation to cluster admin on multi-tenant environments" was fixed in flux2 **v0.15.0**.
[Flux version 0.24]: https://github.com/fluxcd/flux2/releases/tag/v0.24.0
[serviceAccountName]: https://fluxcd.io/docs/components/kustomize/api/#kustomize.toolkit.fluxcd.io/v1beta2.KustomizationSpec
[kubeconfig]: https://fluxcd.io/docs/components/kustomize/api/#kustomize.toolkit.fluxcd.io/v1beta2.KubeConfig
[access-from-ref]: https://fluxcd.io/docs/components/image/imagerepositories/#allow-cross-namespace-references
[Flux API]: https://fluxcd.io/docs/components/
[flux-rbac]: https://github.com/fluxcd/flux2/tree/v0.24.0/manifests/rbac
[k8s-ns]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
[k8s-rbac]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
[k8s-cluster-admin]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
[multi-tenancy-eg]: https://github.com/fluxcd/flux2-multi-tenancy/blob/main/infrastructure/kyverno-policies/flux-multi-tenancy.yaml

View File

@@ -1,225 +0,0 @@
# RFC-0004 Flux Multi-Tenancy
**Status:** provisional
**Creation date:** 2021-11-15
**Last update:** 2021-12-17
## Summary
This RFC explains the mechanisms available in Flux for implementing multi-tenancy, defines two
models for multi-tenancy, and gives reference implementations for those models.
## Motivation
To this point, the Flux project has provided [examples of multi-tenancy][mt], but not explained exactly
how they relate to Flux's authorisation model. This RFC explains two multi-tenancy implementations,
their security properties, and how they are implemented within the authorisation model
as defined in [RFC-0001](https://github.com/fluxcd/flux2/pull/2212).
### Goals
- Explain the mechanisms available in Flux for supporting multi-tenancy
- Define two models for multi-tenancy, "soft multi-tenancy" and "hard multi-tenancy".
- Explain when each model is appropriate.
- Describe a reference implementation of each model with Flux.
### Non-Goals
- Give an exhaustive account of multi-tenancy implementations in general.
- Provide an [end-to-end workflow][mt] of
how to set up multi-tenancy with Flux.
## Introduction
Flux allows different organizations and/or teams to share the same Kubernetes control plane; this is
referred to as "multi-tenancy". To make this safe, Flux supports segmentation and isolation of
resources by using namespaces and role-based access control ("RBAC"), and integrating with
Kubernetes Cluster API.
The following subsections explain the existing mechanisms used for safe multi-tenancy.
### Flux's authorisation model
Flux defers to Kubernetes' native RBAC to specify which operations are authorised when processing
the custom resources in the Flux API. By default, this means operations are constrained by the
service account under which the controllers run, which (again, by default) has the `cluster-admin`
role bound to it. This is convenient for a deployment in which all users are trusted.
In a multi-tenant deployment, each tenant needs to be restricted in the operations that can be done
on their behalf. Since tenants control Flux via its API objects, this becomes a matter of attaching
RBAC rules to Flux API objects. There are two mechanisms that do this, "impersonation" and "remote
apply".
#### Impersonation
The Kustomize controller and Helm controller both apply arbitrary sets of Kubernetes configuration
to a cluster. These controllers are subject to authorisation on two counts:
- when accessing Kubernetes resources that are needed for a
particular "apply" operation -- for example, a secret referenced in
the field `.spec.valuesFrom` in a `HelmRelease`;
- when creating, watching, updating and deleting Kubernetes resources
in the process of applying a piece of configuration.
To give users control over this authorisation, these two controllers will _impersonate_ (assume the
identity of) a service account mentioned in the apply specification (e.g., the field
`.spec.serviceAccountName` in a [`Kustomization` object][kcsa]
or in a [`HelmRelease` object][hcsa]) for both accessing resources and applying configuration.
This lets a user constrain the operations mentioned above with RBAC.
As stated in [RFC-0003](https://github.com/fluxcd/flux2/pull/2093),
the platform admins can configure Flux to enforce service account impersonation
by setting a default service account name when `.spec.serviceAccountName` is not specified.
#### Remote apply
The Kustomize controller and Helm controller are able to apply a set of configuration to a cluster
other than the cluster in which they run. If the specification [refers to a secret containing a
"kubeconfig" file][kubeconfig], the controller will construct a client using that kubeconfig, then
the client used to apply the specified set of configuration. The effect of this is that the
configuration will be applied as the user given in the kubeconfig; often this is a user with the
`cluster-admin` role bound to it, but not necessarily so.
## Assumptions made by the multi-tenancy models
### User Roles
The tenancy models assume two types of user: platform admins and tenants.
Besides installing Flux, all the other operations (deploy applications, configure ingress, policies, etc)
do not require users to have direct access to the Kubernetes API. Flux acts as a proxy between users and
the Kubernetes API, using Git as source of truth for the cluster desired state. Changes to the clusters
and workloads configuration can be made in a collaborative manner, where the various teams responsible for
the delivery process propose, review and approve changes via pull request workflows.
#### Platform Admins
The platform admins have unrestricted access to Kubernetes API.
They are responsible for installing Flux and granting Flux
access to the sources (Git, Helm, OCI repositories) that make up the cluster(s) control plane desired state.
The repository(s) owned by the platform admins are reconciled on the cluster(s) by Flux, under
the [cluster-admin](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles)
Kubernetes cluster role.
Example of operations performed by platform admins:
- Bootstrap Flux onto cluster(s).
- Extend the Kubernetes API with custom resource definitions and validation webhooks.
- Configure various controllers for ingress, storage, logging, monitoring, progressive delivery, etc.
- Set up namespaces for tenants and define their level of access with Kubernetes RBAC.
- Onboard tenants by registering their Git repositories with Flux.
#### Tenants
The tenants have restricted access to the cluster(s) according to the Kubernetes RBAC configured
by the platform admins. The repositories owned by tenants are reconciled on the cluster(s) by Flux,
under the Kubernetes account(s) assigned by platform admins.
Example of operations performed by tenants:
- Register their sources with Flux (`GitRepositories`, `HelmRepositories` and `Buckets`).
- Deploy workload(s) into their namespace(s) using Flux custom resources (`Kustomizations` and `HelmReleases`).
- Automate application updates using Flux custom resources (`ImageRepositories`, `ImagePolicies` and `ImageUpdateAutomations`).
- Configure the release pipeline(s) using Flagger custom resources (`Canaries` and `MetricsTemplates`).
- Setup webhooks and alerting for their release pipeline(s) using Flux custom resources (`Receivers` and `Alerts`).
## Tenancy Models
The Kubernetes tenancy models supported by Flux are: soft multi-tenancy and hard multi-tenancy.
For an overview of the Kubernetes multi-tenant architecture please consult the following documentation:
- [Three Tenancy Models For Kubernetes](https://kubernetes.io/blog/2021/04/15/three-tenancy-models-for-kubernetes/)
- [GKE multi-tenancy overview](https://cloud.google.com/kubernetes-engine/docs/concepts/multitenancy-overview)
- [EKS multi-tenancy best practices](https://aws.github.io/aws-eks-best-practices/security/docs/multitenancy/)
### Soft Multi-Tenancy
With soft multi-tenancy, the platform admins use Kubernetes constructs such as namespaces, accounts,
roles and role bindings to create a logical separation between tenants.
When Flux deploys workloads from a repository belonging to a tenant, it uses the Kubernetes account assigned to that
tenant to perform the git-to-cluster reconciliation. By leveraging Kubernetes RBAC, Flux can ensure
that the operations performed by tenants are restricted to their namespaces.
Note that with this model, tenants share cluster-wide resources such as
`ClusterRoles`, `CustomResourceDefinitions`, `IngressClasses`, `StorageClasses`,
and they cannot create or alter these resources.
If a tenant adds a cluster-scoped resource definition to their repository,
Flux will fail the git-to-cluster reconciliation due to Kubernetes RBAC restrictions.
To restrict the reconciliation of tenant's sources, a Kubernetes service account name can be specified
in Flux `Kustomizations` and `HelmReleases` under `.spec.serviceAccountName`. Please consult the Flux
documentation for more details:
- [Kustomization API: Role-based access control][kcsa]
- [HelmRelease API: Role-based access control][hcsa]
- [Flux multi-tenancy example repository][mt]
Note that with soft multi-tenancy, true tenant isolation requires security measures beyond Kubernetes RBAC.
Please refer to the Kubernetes [security considerations documentation](https://kubernetes.io/blog/2021/04/15/three-tenancy-models-for-kubernetes/#security-considerations)
for more details on how to harden shared clusters.
#### Tenants Onboarding
When onboarding tenants, platform admins have the option to assign namespaces, set
permissions and register the tenants main repositories onto clusters.
The Flux CLI offers an easy way of generating all the Kubernetes manifests needed to onboard tenants:
- `flux create tenant` command generates namespaces, service accounts and Kubernetes RBAC
with restricted access to the cluster resources, given tenants access only to their namespaces.
- `flux create secret git` command generates SSH keys used by Flux to clone the tenants repositories.
- `flux create source git` command generates the configuration that tells Flux which repositories belong to tenants.
- `flux create kustomization` command generates the configuration that tells Flux how to reconcile the manifests found in the tenants repositories.
Once the tenants main repositories are registered on the cluster(s), the tenants can configure their app delivery
in Git using Kubernetes namespace-scoped resources such as `Deployments`, `Services`, Flagger `Canaries`,
Flux `GitRepositories`, `Kustomizations`, `HelmRepositories`, `HelmReleases`, `ImageUpdateAutomations`,
`Alerts`, `Receivers`, etc.
### Hard Multi-Tenancy
With hard multi-tenancy, the platform admins create dedicated clusters for each tenant.
When the tenants's clusters are created with Kubernetes Cluster API, the Flux instance
installed on the management cluster is responsible for reconciling the cluster
definitions belonging to tenants.
To enable GitOps for the tenant's clusters, the platform admins can configure the Flux instance running on the
management cluster to connect to the tenant's cluster using the kubeconfig generated by the Cluster API provider
or by creating kubeconfig secrets for the clusters created by other means than Cluster API.
To configure Flux reconciliation of remote clusters, a Kubernetes secret containing a `kubeConfig` can be specified
in Flux `Kustomizations` and `HelmReleases` under `.spec.kubeConfig.secretRef`. Please consult the Flux API
documentation for more details:
- [Kustomization API: Remote Clusters](https://fluxcd.io/docs/components/kustomize/kustomization/#remote-clusters--cluster-api)
- [HelmRelease API: Remote Clusters](https://fluxcd.io/docs/components/helm/helmreleases/#remote-clusters--cluster-api)
Note that with hard multi-tenancy, tenants have full access to cluster-wide resources, so they have the option
to manage Flux independently of platform admins, by deploying a Flux instance on each cluster.
#### Caveats
When using a Kubernetes Cluster API provider, the `kubeConfig` secret is automatically generated and Flux can
make use of it without any manual actions. For clusters created by other means than Cluster API, the
platform team has to create the `kubeConfig` secrets to allow Flux access to the remote clusters.
As of Flux v0.24 (Nov 2021), we don't provide any guidance for cluster admins on how to generate the `kubeConfig` secrets.
## Implementation History
- Soft multi-tenancy based on service account impersonation was first released in flux2 **v0.0.1**.
- Generating namespaces and RBAC for defining tenants with `flux create tenant` was first released in flux2 **v0.1.0**.
- Hard multi-tenancy based on remote cluster reconciliation was first released in flux2 **v0.2.0**.
- Soft multi-tenancy end-to-end workflow example was first published on 27 Nov 2020 at
[fluxcd/flux2-multi-tenancy](https://github.com/fluxcd/flux2-multi-tenancy).
- Soft multi-tenancy [CVE-2021-41254](https://github.com/fluxcd/kustomize-controller/security/advisories/GHSA-35rf-v2jv-gfg7)
"Privilege escalation to cluster admin on multi-tenant environments" was fixed in flux2 **v0.15.0**.
[mt]: https://github.com/fluxcd/flux2-multi-tenancy/tree/v0.1.0
[kcsa]: https://fluxcd.io/docs/components/kustomize/kustomization/#role-based-access-control
[hcsa]: https://fluxcd.io/docs/components/helm/helmreleases/#role-based-access-control
[kubeconfig]: https://fluxcd.io/docs/components/kustomize/api/#kustomize.toolkit.fluxcd.io/v1beta2.KubeConfig

View File

@@ -1,25 +1,112 @@
module github.com/fluxcd/flux2/tests/azure
go 1.16
go 1.17
require (
github.com/Azure/azure-event-hubs-go/v3 v3.3.13
github.com/fluxcd/helm-controller/api v0.14.0
github.com/fluxcd/image-automation-controller/api v0.18.0
github.com/fluxcd/image-reflector-controller/api v0.14.0
github.com/fluxcd/kustomize-controller/api v0.18.1
github.com/fluxcd/notification-controller/api v0.19.0
github.com/fluxcd/pkg/apis/meta v0.10.1
github.com/fluxcd/pkg/runtime v0.12.2
github.com/fluxcd/source-controller/api v0.19.0
github.com/fluxcd/helm-controller/api v0.15.0
github.com/fluxcd/image-automation-controller/api v0.19.0
github.com/fluxcd/image-reflector-controller/api v0.15.0
github.com/fluxcd/kustomize-controller/api v0.19.1
github.com/fluxcd/notification-controller/api v0.20.1
github.com/fluxcd/pkg/apis/meta v0.10.2
github.com/fluxcd/pkg/runtime v0.12.3
github.com/fluxcd/source-controller/api v0.20.1
github.com/hashicorp/terraform-exec v0.14.0
github.com/libgit2/git2go/v31 v31.6.1
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5
github.com/stretchr/testify v1.7.0
github.com/whilp/git-urls v1.0.0
go.uber.org/multierr v1.6.0
k8s.io/api v0.22.2
k8s.io/apimachinery v0.22.2
k8s.io/client-go v0.22.2
sigs.k8s.io/controller-runtime v0.10.2
k8s.io/api v0.23.1
k8s.io/apimachinery v0.23.1
k8s.io/client-go v0.23.1
sigs.k8s.io/controller-runtime v0.11.0
)
require (
cloud.google.com/go v0.81.0 // indirect
cloud.google.com/go/storage v1.10.0 // indirect
github.com/Azure/azure-amqp-common-go/v3 v3.0.1 // indirect
github.com/Azure/azure-sdk-for-go v51.1.0+incompatible // indirect
github.com/Azure/go-amqp v0.13.12 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/aws/aws-sdk-go v1.15.78 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/devigned/tab v0.1.1 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/fluxcd/pkg/apis/acl v0.0.3 // indirect
github.com/fluxcd/pkg/apis/kustomize v0.3.1 // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/go-logr/logr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/googleapis/gax-go/v2 v2.0.5 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.5.3 // indirect
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-uuid v1.0.1 // indirect
github.com/hashicorp/go-version v1.3.0 // indirect
github.com/hashicorp/terraform-json v0.12.0 // indirect
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/jstemmer/go-junit-report v0.9.1 // indirect
github.com/klauspost/compress v1.11.2 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ulikunitz/xz v0.5.8 // indirect
github.com/zclconf/go-cty v1.8.4 // indirect
go.opencensus.io v0.23.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/api v0.44.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2 // indirect
google.golang.org/grpc v1.40.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/apiextensions-apiserver v0.23.1 // indirect
k8s.io/klog/v2 v2.30.0 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
k8s.io/utils v0.0.0-20211208161948-7d6a63dca704 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
// Fix for CVE-2020-29652: https://github.com/golang/crypto/commit/8b5274cf687fd9316b4108863654cc57385531e8
// Fix for CVE-2021-43565: https://github.com/golang/crypto/commit/5770296d904e90f15f38f77dfc2e43fdf5efc083
replace golang.org/x/crypto => golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3

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