Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3dfd0bc2e1 | ||
|
|
10ff99542f | ||
|
|
2449030ab8 | ||
|
|
3e85901f40 | ||
|
|
73b1576f81 | ||
|
|
cdb5b7c9a2 | ||
|
|
d9331b0c91 | ||
|
|
b6a8163dd9 | ||
|
|
185252ba48 | ||
|
|
043d37921b | ||
|
|
02fb8d9958 | ||
|
|
cfa6c0a178 | ||
|
|
e8b52bf2fc | ||
|
|
85fbb780bf | ||
|
|
bd9f9bf518 | ||
|
|
077860fff1 | ||
|
|
d29a4ee4d2 | ||
|
|
6d2e34e9b2 | ||
|
|
0b6969537b | ||
|
|
dc6b0d0f0d | ||
|
|
b4dbb178fe | ||
|
|
4cf5290989 | ||
|
|
6ffd2222c2 | ||
|
|
e7725911a7 | ||
|
|
0c1664cd01 | ||
|
|
0239307d8e | ||
|
|
9f10b6be1b | ||
|
|
01f613b39e | ||
|
|
b775d11a70 | ||
|
|
022576697f | ||
|
|
065d0b2c06 | ||
|
|
ed4718205a | ||
|
|
a29d0c536d | ||
|
|
eaeb8ca5c1 | ||
|
|
2092c14aca | ||
|
|
69f38b8c77 | ||
|
|
d2cdd02a57 | ||
|
|
095c8323a1 | ||
|
|
accb4c915e | ||
|
|
242809f61d | ||
|
|
c4907cf6c6 | ||
|
|
a4b9191fa3 | ||
|
|
5fd3d0bd41 | ||
|
|
ba6da23323 | ||
|
|
0328bb14ce | ||
|
|
2b7a0f3fd4 | ||
|
|
527886bea0 | ||
|
|
98078a0c65 |
19
.github/aur/flux-bin/PKGBUILD.template
vendored
19
.github/aur/flux-bin/PKGBUILD.template
vendored
@@ -8,18 +8,20 @@ pkgdesc="Open and extensible continuous delivery solution for Kubernetes"
|
|||||||
url="https://fluxcd.io/"
|
url="https://fluxcd.io/"
|
||||||
arch=("x86_64" "armv6h" "armv7h" "aarch64")
|
arch=("x86_64" "armv6h" "armv7h" "aarch64")
|
||||||
license=("APACHE")
|
license=("APACHE")
|
||||||
optdepends=("kubectl")
|
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
|
||||||
|
'bash-completion: auto-completion for flux in Bash',
|
||||||
|
'zsh-completions: auto-completion for flux in ZSH')
|
||||||
source_x86_64=(
|
source_x86_64=(
|
||||||
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_amd64.tar.gz"
|
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_amd64.tar.gz"
|
||||||
)
|
)
|
||||||
source_armv6h=(
|
source_armv6h=(
|
||||||
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
|
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
|
||||||
)
|
)
|
||||||
source_armv7h=(
|
source_armv7h=(
|
||||||
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
|
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm.tar.gz"
|
||||||
)
|
)
|
||||||
source_aarch64=(
|
source_aarch64=(
|
||||||
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm64.tar.gz"
|
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/releases/download/v${pkgver}/flux_${pkgver}_linux_arm64.tar.gz"
|
||||||
)
|
)
|
||||||
sha256sums_x86_64=(
|
sha256sums_x86_64=(
|
||||||
${SHA256SUM_AMD64}
|
${SHA256SUM_AMD64}
|
||||||
@@ -33,7 +35,12 @@ sha256sums_armv7h=(
|
|||||||
sha256sums_aarch64=(
|
sha256sums_aarch64=(
|
||||||
${SHA256SUM_ARM64}
|
${SHA256SUM_ARM64}
|
||||||
)
|
)
|
||||||
|
_srcname=flux
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
install -Dm755 flux "$pkgdir/usr/bin/flux"
|
install -Dm755 ${_srcname} "${pkgdir}/usr/bin/${_srcname}"
|
||||||
|
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion bash | install -Dm644 /dev/stdin "${pkgdir}/usr/share/bash-completion/completions/${_srcname}"
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion fish | install -Dm644 /dev/stdin "${pkgdir}/usr/share/fish/vendor_completions.d/${_srcname}.fish"
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion zsh | install -Dm644 /dev/stdin "${pkgdir}/usr/share/zsh/site-functions/_${_srcname}"
|
||||||
}
|
}
|
||||||
|
|||||||
28
.github/aur/flux-go/PKGBUILD.template
vendored
28
.github/aur/flux-go/PKGBUILD.template
vendored
@@ -12,32 +12,40 @@ provides=("flux-bin")
|
|||||||
conflicts=("flux-bin")
|
conflicts=("flux-bin")
|
||||||
replaces=("flux-cli")
|
replaces=("flux-cli")
|
||||||
depends=("glibc")
|
depends=("glibc")
|
||||||
makedepends=("go")
|
makedepends=('go>=1.16', 'kustomize>=3.0')
|
||||||
optdepends=("kubectl")
|
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
|
||||||
|
'bash-completion: auto-completion for flux in Bash',
|
||||||
|
'zsh-completions: auto-completion for flux in ZSH')
|
||||||
source=(
|
source=(
|
||||||
"$pkgname-$pkgver.tar.gz::https://github.com/fluxcd/flux2/archive/v$pkgver.tar.gz"
|
"${pkgname}-${pkgver}.tar.gz::https://github.com/fluxcd/flux2/archive/v${pkgver}.tar.gz"
|
||||||
)
|
)
|
||||||
sha256sums=(
|
sha256sums=(
|
||||||
${SHA256SUM}
|
${SHA256SUM}
|
||||||
)
|
)
|
||||||
|
_srcname=flux
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
cd "flux2-$pkgver"
|
cd "flux2-${pkgver}"
|
||||||
export CGO_LDFLAGS="$LDFLAGS"
|
export CGO_LDFLAGS="$LDFLAGS"
|
||||||
export CGO_CFLAGS="$CFLAGS"
|
export CGO_CFLAGS="$CFLAGS"
|
||||||
export CGO_CXXFLAGS="$CXXFLAGS"
|
export CGO_CXXFLAGS="$CXXFLAGS"
|
||||||
export CGO_CPPFLAGS="$CPPFLAGS"
|
export CGO_CPPFLAGS="$CPPFLAGS"
|
||||||
export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"
|
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
|
||||||
go build -ldflags "-X main.VERSION=$pkgver" -o flux-bin ./cmd/flux
|
./manifests/scripts/bundle.sh "${PWD}/manifests" "${PWD}/cmd/flux/manifests"
|
||||||
|
go build -ldflags "-linkmode=external -X main.VERSION=${pkgver}" -o ${_srcname} ./cmd/flux
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
cd "flux2-$pkgver"
|
cd "flux2-${pkgver}"
|
||||||
make test
|
make test
|
||||||
}
|
}
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
cd "flux2-$pkgver"
|
cd "flux2-${pkgver}"
|
||||||
install -Dm755 flux-bin "$pkgdir/usr/bin/flux"
|
install -Dm755 ${_srcname} "${pkgdir}/usr/bin/${_srcname}"
|
||||||
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||||
|
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion bash | install -Dm644 /dev/stdin "${pkgdir}/usr/share/bash-completion/completions/${_srcname}"
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion fish | install -Dm644 /dev/stdin "${pkgdir}/usr/share/fish/vendor_completions.d/${_srcname}.fish"
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion zsh | install -Dm644 /dev/stdin "${pkgdir}/usr/share/zsh/site-functions/_${_srcname}"
|
||||||
}
|
}
|
||||||
|
|||||||
20
.github/aur/flux-scm/PKGBUILD.template
vendored
20
.github/aur/flux-scm/PKGBUILD.template
vendored
@@ -11,12 +11,15 @@ license=("APACHE")
|
|||||||
provides=("flux-bin")
|
provides=("flux-bin")
|
||||||
conflicts=("flux-bin")
|
conflicts=("flux-bin")
|
||||||
depends=("glibc")
|
depends=("glibc")
|
||||||
makedepends=("go")
|
makedepends=('go>=1.16', 'kustomize>=3.0')
|
||||||
optdepends=("kubectl")
|
optdepends=('kubectl: for apply actions on the Kubernetes cluster',
|
||||||
|
'bash-completion: auto-completion for flux in Bash',
|
||||||
|
'zsh-completions: auto-completion for flux in ZSH')
|
||||||
source=(
|
source=(
|
||||||
"git+https://github.com/fluxcd/flux2.git"
|
"git+https://github.com/fluxcd/flux2.git"
|
||||||
)
|
)
|
||||||
md5sums=('SKIP')
|
md5sums=('SKIP')
|
||||||
|
_srcname=flux
|
||||||
|
|
||||||
pkgver() {
|
pkgver() {
|
||||||
cd "flux2"
|
cd "flux2"
|
||||||
@@ -29,8 +32,9 @@ build() {
|
|||||||
export CGO_CFLAGS="$CFLAGS"
|
export CGO_CFLAGS="$CFLAGS"
|
||||||
export CGO_CXXFLAGS="$CXXFLAGS"
|
export CGO_CXXFLAGS="$CXXFLAGS"
|
||||||
export CGO_CPPFLAGS="$CPPFLAGS"
|
export CGO_CPPFLAGS="$CPPFLAGS"
|
||||||
export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw"
|
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
|
||||||
go build -ldflags "-X main.VERSION=$pkgver" -o flux-bin ./cmd/flux
|
make cmd/flux/manifests
|
||||||
|
go build -ldflags "-linkmode=external -X main.VERSION=${pkgver}" -o ${_srcname} ./cmd/flux
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
@@ -40,6 +44,10 @@ check() {
|
|||||||
|
|
||||||
package() {
|
package() {
|
||||||
cd "flux2"
|
cd "flux2"
|
||||||
install -Dm755 flux-bin "$pkgdir/usr/bin/flux"
|
install -Dm755 ${_srcname} "${pkgdir}/usr/bin/${_srcname}"
|
||||||
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||||
|
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion bash | install -Dm644 /dev/stdin "${pkgdir}/usr/share/bash-completion/completions/${_srcname}"
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion fish | install -Dm644 /dev/stdin "${pkgdir}/usr/share/fish/vendor_completions.d/${_srcname}.fish"
|
||||||
|
"${pkgdir}/usr/bin/${_srcname}" completion zsh | install -Dm644 /dev/stdin "${pkgdir}/usr/share/zsh/site-functions/_${_srcname}"
|
||||||
}
|
}
|
||||||
|
|||||||
28
.github/workflows/bootstrap.yaml
vendored
28
.github/workflows/bootstrap.yaml
vendored
@@ -30,16 +30,22 @@ jobs:
|
|||||||
uses: fluxcd/pkg//actions/kustomize@main
|
uses: fluxcd/pkg//actions/kustomize@main
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
make build-manifests
|
make cmd/flux/manifests
|
||||||
go build -o /tmp/flux ./cmd/flux
|
go build -o /tmp/flux ./cmd/flux
|
||||||
- name: Set outputs
|
- name: Set outputs
|
||||||
id: vars
|
id: vars
|
||||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
run: |
|
||||||
|
REPOSITORY_NAME=${{ github.event.repository.name }}
|
||||||
|
BRANCH_NAME=${GITHUB_REF##*/}
|
||||||
|
COMMIT_SHA=$(git rev-parse HEAD)
|
||||||
|
PSEUDO_RAND_SUFFIX=$(echo "${BRANCH_NAME}-${COMMIT_SHA}" | shasum | awk '{print $1}')
|
||||||
|
TEST_REPO_NAME="${REPOSITORY_NAME}-${PSEUDO_RAND_SUFFIX}"
|
||||||
|
echo "::set-output name=test_repo_name::$TEST_REPO_NAME"
|
||||||
- name: bootstrap init
|
- name: bootstrap init
|
||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
||||||
--owner=fluxcd-testing \
|
--owner=fluxcd-testing \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
--repository=${{ steps.vars.outputs.test_repo_name }} \
|
||||||
--branch=main \
|
--branch=main \
|
||||||
--path=test-cluster
|
--path=test-cluster
|
||||||
env:
|
env:
|
||||||
@@ -48,7 +54,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
||||||
--owner=fluxcd-testing \
|
--owner=fluxcd-testing \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
--repository=${{ steps.vars.outputs.test_repo_name }} \
|
||||||
--branch=main \
|
--branch=main \
|
||||||
--path=test-cluster
|
--path=test-cluster
|
||||||
env:
|
env:
|
||||||
@@ -61,19 +67,19 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
||||||
--owner=fluxcd-testing \
|
--owner=fluxcd-testing \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
--repository=${{ steps.vars.outputs.test_repo_name }} \
|
||||||
--branch=main \
|
--branch=main \
|
||||||
--path=test-cluster
|
--path=test-cluster
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
||||||
- name: delete repository
|
- name: delete repository
|
||||||
run: |
|
run: |
|
||||||
/tmp/flux bootstrap github --manifests ./manifests/install/ \
|
curl \
|
||||||
--owner=fluxcd-testing \
|
-X DELETE \
|
||||||
--repository=flux-test-${{ steps.vars.outputs.sha_short }} \
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
--branch=main \
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
--path=test-cluster \
|
--fail --silent \
|
||||||
--delete
|
https://api.github.com/repos/fluxcd-testing/${{ steps.vars.outputs.test_repo_name }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
|
||||||
- name: Debug failure
|
- name: Debug failure
|
||||||
|
|||||||
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@@ -30,8 +30,8 @@ jobs:
|
|||||||
uses: fluxcd/pkg//actions/kustomize@main
|
uses: fluxcd/pkg//actions/kustomize@main
|
||||||
- name: Generate manifests
|
- name: Generate manifests
|
||||||
run: |
|
run: |
|
||||||
make build-manifests
|
make cmd/flux/manifests
|
||||||
./manifests/scripts/bundle.sh ./output manifests.tar.gz
|
./manifests/scripts/bundle.sh "" ./output manifests.tar.gz
|
||||||
kustomize build ./manifests/install > ./output/install.yaml
|
kustomize build ./manifests/install > ./output/install.yaml
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v1
|
uses: goreleaser/goreleaser-action@v1
|
||||||
|
|||||||
2
.github/workflows/scan.yaml
vendored
2
.github/workflows/scan.yaml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
uses: fluxcd/pkg//actions/kustomize@main
|
uses: fluxcd/pkg//actions/kustomize@main
|
||||||
- name: Build manifests
|
- name: Build manifests
|
||||||
run: |
|
run: |
|
||||||
make build-manifests
|
make cmd/flux/manifests
|
||||||
- name: Run Snyk to check for vulnerabilities
|
- name: Run Snyk to check for vulnerabilities
|
||||||
uses: snyk/actions/golang@master
|
uses: snyk/actions/golang@master
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|||||||
2
.github/workflows/update.yaml
vendored
2
.github/workflows/update.yaml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
# bump kustomize
|
# bump kustomize
|
||||||
sed -i "s/\($1\/releases\/download\/\)v.*\(\/.*\)/\1${RELEASE_VERSION}\2/g" "manifests/bases/$1/kustomization.yaml"
|
sed -i "s/\($1\/releases\/download\/\)v.*\(\/.*\)/\1${RELEASE_VERSION}\2/g" "manifests/bases/$1/kustomization.yaml"
|
||||||
|
|
||||||
if [[ ! -z $(go list -m all | grep "github.com/fluxcd/$1/api" | awk '{print $2}') ]]; then
|
if [[ ! -z $(grep "github.com/fluxcd/$1/api" go.mod | awk '{print $2}') ]]; then
|
||||||
# bump go mod
|
# bump go mod
|
||||||
go mod edit -require="github.com/fluxcd/$1/api@${RELEASE_VERSION}"
|
go mod edit -require="github.com/fluxcd/$1/api@${RELEASE_VERSION}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -48,11 +48,13 @@ you might want to take a look at the [introductory talk and demo](https://www.yo
|
|||||||
|
|
||||||
This project is composed of:
|
This project is composed of:
|
||||||
|
|
||||||
- [/f/flux2](https://github.com/fluxcd/flux2): The Flux CLI
|
- [flux2](https://github.com/fluxcd/flux2): The Flux CLI
|
||||||
- [/f/source-manager](https://github.com/fluxcd/source-controller): Kubernetes operator for managing sources
|
- [source-manager](https://github.com/fluxcd/source-controller): Kubernetes operator for managing sources (Git and Helm repositories, S3-compatible Buckets)
|
||||||
- [/f/kustomize-controller](https://github.com/fluxcd/kustomize-controller): Kubernetes operator for building GitOps pipelines with Kustomize
|
- [kustomize-controller](https://github.com/fluxcd/kustomize-controller): Kubernetes operator for building GitOps pipelines with Kustomize
|
||||||
- [/f/helm-controller](https://github.com/fluxcd/helm-controller): Kubernetes operator for building GitOps pipelines with Helm
|
- [helm-controller](https://github.com/fluxcd/helm-controller): Kubernetes operator for building GitOps pipelines with Helm
|
||||||
- [/f/notification-controller](https://github.com/fluxcd/notification-controller): Kubernetes operator for handling inbound and outbound events
|
- [notification-controller](https://github.com/fluxcd/notification-controller): Kubernetes operator for handling inbound and outbound events
|
||||||
|
- [image-reflector-controller](https://github.com/fluxcd/image-reflector-controller): Kubernetes operator for scanning container registries
|
||||||
|
- [image-automation-controller](https://github.com/fluxcd/image-automation-controller): Kubernetes operator for patches container image tags in Git
|
||||||
|
|
||||||
### Understanding the code
|
### Understanding the code
|
||||||
|
|
||||||
@@ -63,6 +65,12 @@ for source changes.
|
|||||||
|
|
||||||
### How to run the test suite
|
### How to run the test suite
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
|
||||||
|
* go >= 1.16
|
||||||
|
* kubectl >= 1.18
|
||||||
|
* kustomize >= 3.1
|
||||||
|
|
||||||
You can run the unit tests by simply doing
|
You can run the unit tests by simply doing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
11
Makefile
11
Makefile
@@ -1,4 +1,7 @@
|
|||||||
VERSION?=$(shell grep 'VERSION' cmd/flux/main.go | awk '{ print $$4 }' | tr -d '"')
|
VERSION?=$(shell grep 'VERSION' cmd/flux/main.go | awk '{ print $$4 }' | tr -d '"')
|
||||||
|
EMBEDDED_MANIFESTS_TARGET=cmd/flux/manifests
|
||||||
|
|
||||||
|
rwildcard=$(foreach d,$(wildcard $(addsuffix *,$(1))),$(call rwildcard,$(d)/,$(2)) $(filter $(subst *,%,$(2)),$(d)))
|
||||||
|
|
||||||
all: test build
|
all: test build
|
||||||
|
|
||||||
@@ -11,13 +14,13 @@ fmt:
|
|||||||
vet:
|
vet:
|
||||||
go vet ./...
|
go vet ./...
|
||||||
|
|
||||||
test: build-manifests tidy fmt vet docs
|
test: $(EMBEDDED_MANIFESTS_TARGET) tidy fmt vet docs
|
||||||
go test ./... -coverprofile cover.out
|
go test ./... -coverprofile cover.out
|
||||||
|
|
||||||
build-manifests:
|
$(EMBEDDED_MANIFESTS_TARGET): $(call rwildcard,manifests/,*.yaml *.json)
|
||||||
./manifests/scripts/bundle.sh
|
./manifests/scripts/bundle.sh
|
||||||
|
|
||||||
build:
|
build: $(EMBEDDED_MANIFESTS_TARGET)
|
||||||
CGO_ENABLED=0 go build -o ./bin/flux ./cmd/flux
|
CGO_ENABLED=0 go build -o ./bin/flux ./cmd/flux
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@@ -25,7 +28,7 @@ install:
|
|||||||
|
|
||||||
.PHONY: docs
|
.PHONY: docs
|
||||||
docs:
|
docs:
|
||||||
rm docs/cmd/*
|
rm -rf docs/cmd/*
|
||||||
mkdir -p ./docs/cmd && go run ./cmd/flux/ docgen
|
mkdir -p ./docs/cmd && go run ./cmd/flux/ docgen
|
||||||
|
|
||||||
install-dev:
|
install-dev:
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
||||||
kus "github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
|
kus "github.com/fluxcd/flux2/pkg/manifestgen/kustomization"
|
||||||
"github.com/fluxcd/flux2/pkg/manifestgen/sync"
|
"github.com/fluxcd/flux2/pkg/manifestgen/sync"
|
||||||
|
"github.com/fluxcd/flux2/pkg/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bootstrapCmd = &cobra.Command{
|
var bootstrapCmd = &cobra.Command{
|
||||||
@@ -176,19 +177,24 @@ func generateInstallManifests(targetPath, namespace, tmpDir string, localManifes
|
|||||||
func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error {
|
func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error {
|
||||||
kubectlArgs := []string{"apply", "-f", manifestPath}
|
kubectlArgs := []string{"apply", "-f", manifestPath}
|
||||||
if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
statusChecker, err := NewStatusChecker(time.Second, rootArgs.timeout)
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
statusChecker, err := status.NewStatusChecker(kubeConfig, time.Second, rootArgs.timeout, logger)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
componentRefs, err := buildComponentObjectRefs(components...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("install failed: %w", err)
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Waitingf("verifying installation")
|
logger.Waitingf("verifying installation")
|
||||||
if err := statusChecker.Assess(components...); err != nil {
|
if err := statusChecker.Assess(componentRefs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ type githubFlags struct {
|
|||||||
hostname string
|
hostname string
|
||||||
path flags.SafeRelativePath
|
path flags.SafeRelativePath
|
||||||
teams []string
|
teams []string
|
||||||
delete bool
|
|
||||||
sshHostname string
|
sshHostname string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,9 +100,6 @@ func init() {
|
|||||||
bootstrapGitHubCmd.Flags().StringVar(&githubArgs.sshHostname, "ssh-hostname", "", "GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one")
|
bootstrapGitHubCmd.Flags().StringVar(&githubArgs.sshHostname, "ssh-hostname", "", "GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one")
|
||||||
bootstrapGitHubCmd.Flags().Var(&githubArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path")
|
bootstrapGitHubCmd.Flags().Var(&githubArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path")
|
||||||
|
|
||||||
bootstrapGitHubCmd.Flags().BoolVar(&githubArgs.delete, "delete", false, "delete repository (used for testing only)")
|
|
||||||
bootstrapGitHubCmd.Flags().MarkHidden("delete")
|
|
||||||
|
|
||||||
bootstrapCmd.AddCommand(bootstrapGitHubCmd)
|
bootstrapCmd.AddCommand(bootstrapGitHubCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,14 +159,6 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
if githubArgs.delete {
|
|
||||||
if err := provider.DeleteRepository(ctx, repository); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger.Successf("repository deleted")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// create GitHub repository if doesn't exists
|
// create GitHub repository if doesn't exists
|
||||||
logger.Actionf("connecting to %s", githubArgs.hostname)
|
logger.Actionf("connecting to %s", githubArgs.hostname)
|
||||||
changed, err := provider.CreateRepository(ctx, repository)
|
changed, err := provider.CreateRepository(ctx, repository)
|
||||||
@@ -260,7 +248,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("git URL parse failed: %w", err)
|
return fmt.Errorf("git URL parse failed: %w", err)
|
||||||
}
|
}
|
||||||
secretOpts.SSHHostname = u.Hostname()
|
secretOpts.SSHHostname = u.Host
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
||||||
secretOpts.RSAKeyBits = 2048
|
secretOpts.RSAKeyBits = 2048
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("git URL parse failed: %w", err)
|
return fmt.Errorf("git URL parse failed: %w", err)
|
||||||
}
|
}
|
||||||
secretOpts.SSHHostname = u.Hostname()
|
secretOpts.SSHHostname = u.Host
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.RSAPrivateKeyAlgorithm
|
||||||
secretOpts.RSAKeyBits = 2048
|
secretOpts.RSAKeyBits = 2048
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import (
|
|||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
||||||
|
"github.com/fluxcd/flux2/pkg/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkCmd = &cobra.Command{
|
var checkCmd = &cobra.Command{
|
||||||
@@ -205,12 +206,17 @@ func componentsCheck() bool {
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
statusChecker, err := NewStatusChecker(time.Second, rootArgs.timeout)
|
statusChecker, err := status.NewStatusChecker(kubeConfig, time.Second, rootArgs.timeout, logger)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -220,10 +226,10 @@ func componentsCheck() bool {
|
|||||||
var list v1.DeploymentList
|
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(rootArgs.namespace), selector); err == nil {
|
||||||
for _, d := range list.Items {
|
for _, d := range list.Items {
|
||||||
if err := statusChecker.Assess(d.Name); err != nil {
|
if ref, err := buildComponentObjectRefs(d.Name); err == nil {
|
||||||
ok = false
|
if err := statusChecker.Assess(ref...); err != nil {
|
||||||
} else {
|
ok = false
|
||||||
logger.Successf("%s: healthy", d.Name)
|
}
|
||||||
}
|
}
|
||||||
for _, c := range d.Spec.Template.Spec.Containers {
|
for _, c := range d.Spec.Template.Spec.Containers {
|
||||||
logger.Actionf(c.Image)
|
logger.Actionf(c.Image)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var createImagePolicyCmd = &cobra.Command{
|
var createImagePolicyCmd = &cobra.Command{
|
||||||
Use: "policy <name>",
|
Use: "policy [name]",
|
||||||
Short: "Create or update an ImagePolicy object",
|
Short: "Create or update an ImagePolicy object",
|
||||||
Long: `The create image policy command generates an ImagePolicy resource.
|
Long: `The create image policy command generates an ImagePolicy resource.
|
||||||
An ImagePolicy object calculates a "latest image" given an image
|
An ImagePolicy object calculates a "latest image" given an image
|
||||||
@@ -40,6 +40,18 @@ repository and a policy, e.g., semver.
|
|||||||
|
|
||||||
The image that sorts highest according to the policy is recorded in
|
The image that sorts highest according to the policy is recorded in
|
||||||
the status of the object.`,
|
the status of the object.`,
|
||||||
|
Example: ` # Create an ImagePolicy to select the latest stable release
|
||||||
|
flux create image policy podinfo \
|
||||||
|
--image-ref=podinfo \
|
||||||
|
--select-semver=">=1.0.0"
|
||||||
|
|
||||||
|
# Create an ImagePolicy to select the latest main branch build tagged as "${GIT_BRANCH}-${GIT_SHA:0:7}-$(date +%s)"
|
||||||
|
flux create image policy podinfo \
|
||||||
|
--image-ref=podinfo \
|
||||||
|
--select-numeric=asc \
|
||||||
|
--filter-regex='^main-[a-f0-9]+-(?P<ts>[0-9]+)' \
|
||||||
|
--filter-extract='$ts'
|
||||||
|
`,
|
||||||
RunE: createImagePolicyRun}
|
RunE: createImagePolicyRun}
|
||||||
|
|
||||||
type imagePolicyFlags struct {
|
type imagePolicyFlags struct {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var createImageRepositoryCmd = &cobra.Command{
|
var createImageRepositoryCmd = &cobra.Command{
|
||||||
Use: "repository <name>",
|
Use: "repository [name]",
|
||||||
Short: "Create or update an ImageRepository object",
|
Short: "Create or update an ImageRepository object",
|
||||||
Long: `The create image repository command generates an ImageRepository resource.
|
Long: `The create image repository command generates an ImageRepository resource.
|
||||||
An ImageRepository object specifies an image repository to scan.`,
|
An ImageRepository object specifies an image repository to scan.`,
|
||||||
|
|||||||
@@ -28,19 +28,38 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var createImageUpdateCmd = &cobra.Command{
|
var createImageUpdateCmd = &cobra.Command{
|
||||||
Use: "update <name>",
|
Use: "update [name]",
|
||||||
Short: "Create or update an ImageUpdateAutomation object",
|
Short: "Create or update an ImageUpdateAutomation object",
|
||||||
Long: `The create image update command generates an ImageUpdateAutomation resource.
|
Long: `The create image update command generates an ImageUpdateAutomation resource.
|
||||||
An ImageUpdateAutomation object specifies an automated update to images
|
An ImageUpdateAutomation object specifies an automated update to images
|
||||||
mentioned in YAMLs in a git repository.`,
|
mentioned in YAMLs in a git repository.`,
|
||||||
|
Example: ` # Configure image updates for the main repository created by flux bootstrap
|
||||||
|
flux create image update flux-system \
|
||||||
|
--git-repo-ref=flux-system \
|
||||||
|
--git-repo-path="./clusters/my-cluster" \
|
||||||
|
--checkout-branch=main \
|
||||||
|
--author-name=flux \
|
||||||
|
--author-email=flux@example.com \
|
||||||
|
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
|
||||||
|
|
||||||
|
# Configure image updates to push changes to a different branch, if the branch doesn't exists it will be created
|
||||||
|
flux create image update flux-system \
|
||||||
|
--git-repo-ref=flux-system \
|
||||||
|
--git-repo-path="./clusters/my-cluster" \
|
||||||
|
--checkout-branch=main \
|
||||||
|
--push-branch=image-updates \
|
||||||
|
--author-name=flux \
|
||||||
|
--author-email=flux@example.com \
|
||||||
|
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
|
||||||
|
`,
|
||||||
RunE: createImageUpdateRun,
|
RunE: createImageUpdateRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
type imageUpdateFlags struct {
|
type imageUpdateFlags struct {
|
||||||
// git checkout spec
|
gitRepoRef string
|
||||||
gitRepoRef string
|
gitRepoPath string
|
||||||
branch string
|
checkoutBranch string
|
||||||
// commit spec
|
pushBranch string
|
||||||
commitTemplate string
|
commitTemplate string
|
||||||
authorName string
|
authorName string
|
||||||
authorEmail string
|
authorEmail string
|
||||||
@@ -50,8 +69,10 @@ var imageUpdateArgs = imageUpdateFlags{}
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flags := createImageUpdateCmd.Flags()
|
flags := createImageUpdateCmd.Flags()
|
||||||
flags.StringVar(&imageUpdateArgs.gitRepoRef, "git-repo-ref", "", "the name of a GitRepository resource with details of the upstream git repository")
|
flags.StringVar(&imageUpdateArgs.gitRepoRef, "git-repo-ref", "", "the name of a GitRepository resource with details of the upstream Git repository")
|
||||||
flags.StringVar(&imageUpdateArgs.branch, "branch", "", "the branch to checkout and push commits to")
|
flags.StringVar(&imageUpdateArgs.gitRepoPath, "git-repo-path", "", "path to the directory containing the manifests to be updated, defaults to the repository root")
|
||||||
|
flags.StringVar(&imageUpdateArgs.checkoutBranch, "checkout-branch", "", "the branch to checkout")
|
||||||
|
flags.StringVar(&imageUpdateArgs.pushBranch, "push-branch", "", "the branch to push commits to, defaults to the checkout branch if not specified")
|
||||||
flags.StringVar(&imageUpdateArgs.commitTemplate, "commit-template", "", "a template for commit messages")
|
flags.StringVar(&imageUpdateArgs.commitTemplate, "commit-template", "", "a template for commit messages")
|
||||||
flags.StringVar(&imageUpdateArgs.authorName, "author-name", "", "the name to use for commit author")
|
flags.StringVar(&imageUpdateArgs.authorName, "author-name", "", "the name to use for commit author")
|
||||||
flags.StringVar(&imageUpdateArgs.authorEmail, "author-email", "", "the email to use for commit author")
|
flags.StringVar(&imageUpdateArgs.authorEmail, "author-email", "", "the email to use for commit author")
|
||||||
@@ -69,8 +90,16 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("a reference to a GitRepository is required (--git-repo-ref)")
|
return fmt.Errorf("a reference to a GitRepository is required (--git-repo-ref)")
|
||||||
}
|
}
|
||||||
|
|
||||||
if imageUpdateArgs.branch == "" {
|
if imageUpdateArgs.checkoutBranch == "" {
|
||||||
return fmt.Errorf("the Git repository branch is required (--branch)")
|
return fmt.Errorf("the Git repository branch is required (--checkout-branch)")
|
||||||
|
}
|
||||||
|
|
||||||
|
if imageUpdateArgs.authorName == "" {
|
||||||
|
return fmt.Errorf("the author name is required (--author-name)")
|
||||||
|
}
|
||||||
|
|
||||||
|
if imageUpdateArgs.authorEmail == "" {
|
||||||
|
return fmt.Errorf("the author email is required (--author-email)")
|
||||||
}
|
}
|
||||||
|
|
||||||
labels, err := parseLabels()
|
labels, err := parseLabels()
|
||||||
@@ -89,9 +118,11 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
|
|||||||
GitRepositoryRef: meta.LocalObjectReference{
|
GitRepositoryRef: meta.LocalObjectReference{
|
||||||
Name: imageUpdateArgs.gitRepoRef,
|
Name: imageUpdateArgs.gitRepoRef,
|
||||||
},
|
},
|
||||||
Branch: imageUpdateArgs.branch,
|
Branch: imageUpdateArgs.checkoutBranch,
|
||||||
|
},
|
||||||
|
Interval: metav1.Duration{
|
||||||
|
Duration: createArgs.interval,
|
||||||
},
|
},
|
||||||
Interval: metav1.Duration{Duration: createArgs.interval},
|
|
||||||
Commit: autov1.CommitSpec{
|
Commit: autov1.CommitSpec{
|
||||||
AuthorName: imageUpdateArgs.authorName,
|
AuthorName: imageUpdateArgs.authorName,
|
||||||
AuthorEmail: imageUpdateArgs.authorEmail,
|
AuthorEmail: imageUpdateArgs.authorEmail,
|
||||||
@@ -100,6 +131,19 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if imageUpdateArgs.pushBranch != "" {
|
||||||
|
update.Spec.Push = &autov1.PushSpec{
|
||||||
|
Branch: imageUpdateArgs.pushBranch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if imageUpdateArgs.gitRepoPath != "" {
|
||||||
|
update.Spec.Update = &autov1.UpdateStrategy{
|
||||||
|
Path: imageUpdateArgs.gitRepoPath,
|
||||||
|
Strategy: autov1.UpdateStrategySetters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if createArgs.export {
|
if createArgs.export {
|
||||||
return printExport(exportImageUpdate(&update))
|
return printExport(exportImageUpdate(&update))
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
opts.SSHHostname = u.Hostname()
|
opts.SSHHostname = u.Host
|
||||||
opts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(secretGitArgs.keyAlgorithm)
|
opts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(secretGitArgs.keyAlgorithm)
|
||||||
opts.RSAKeyBits = int(secretGitArgs.rsaBits)
|
opts.RSAKeyBits = int(secretGitArgs.rsaBits)
|
||||||
opts.ECDSACurve = secretGitArgs.ecdsaCurve.Curve
|
opts.ECDSACurve = secretGitArgs.ecdsaCurve.Curve
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
secretOpts.SSHHostname = u.Hostname()
|
secretOpts.SSHHostname = u.Host
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(sourceGitArgs.keyAlgorithm)
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(sourceGitArgs.keyAlgorithm)
|
||||||
secretOpts.RSAKeyBits = int(sourceGitArgs.keyRSABits)
|
secretOpts.RSAKeyBits = int(sourceGitArgs.keyRSABits)
|
||||||
secretOpts.ECDSACurve = sourceGitArgs.keyECDSACurve.Curve
|
secretOpts.ECDSACurve = sourceGitArgs.keyECDSACurve.Curve
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import (
|
|||||||
var exportSourceBucketCmd = &cobra.Command{
|
var exportSourceBucketCmd = &cobra.Command{
|
||||||
Use: "bucket [name]",
|
Use: "bucket [name]",
|
||||||
Short: "Export Bucket sources in YAML format",
|
Short: "Export Bucket sources in YAML format",
|
||||||
Long: "The export source git command exports on or all Bucket sources in YAML format.",
|
Long: "The export source git command exports one or all Bucket sources in YAML format.",
|
||||||
Example: ` # Export all Bucket sources
|
Example: ` # Export all Bucket sources
|
||||||
flux export source bucket --all > sources.yaml
|
flux export source bucket --all > sources.yaml
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import (
|
|||||||
var exportSourceGitCmd = &cobra.Command{
|
var exportSourceGitCmd = &cobra.Command{
|
||||||
Use: "git [name]",
|
Use: "git [name]",
|
||||||
Short: "Export GitRepository sources in YAML format",
|
Short: "Export GitRepository sources in YAML format",
|
||||||
Long: "The export source git command exports on or all GitRepository sources in YAML format.",
|
Long: "The export source git command exports one or all GitRepository sources in YAML format.",
|
||||||
Example: ` # Export all GitRepository sources
|
Example: ` # Export all GitRepository sources
|
||||||
flux export source git --all > sources.yaml
|
flux export source git --all > sources.yaml
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import (
|
|||||||
var exportSourceHelmCmd = &cobra.Command{
|
var exportSourceHelmCmd = &cobra.Command{
|
||||||
Use: "helm [name]",
|
Use: "helm [name]",
|
||||||
Short: "Export HelmRepository sources in YAML format",
|
Short: "Export HelmRepository sources in YAML format",
|
||||||
Long: "The export source git command exports on or all HelmRepository sources in YAML format.",
|
Long: "The export source git command exports one or all HelmRepository sources in YAML format.",
|
||||||
Example: ` # Export all HelmRepository sources
|
Example: ` # Export all HelmRepository sources
|
||||||
flux export source helm --all > sources.yaml
|
flux export source helm --all > sources.yaml
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||||
@@ -32,8 +34,8 @@ import (
|
|||||||
|
|
||||||
var getCmd = &cobra.Command{
|
var getCmd = &cobra.Command{
|
||||||
Use: "get",
|
Use: "get",
|
||||||
Short: "Get sources and resources",
|
Short: "Get the resources and their status",
|
||||||
Long: "The get sub-commands print the statuses of sources and resources.",
|
Long: "The get sub-commands print the statuses of Flux resources.",
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetFlags struct {
|
type GetFlags struct {
|
||||||
@@ -50,7 +52,7 @@ func init() {
|
|||||||
|
|
||||||
type summarisable interface {
|
type summarisable interface {
|
||||||
listAdapter
|
listAdapter
|
||||||
summariseItem(i int, includeNamespace bool) []string
|
summariseItem(i int, includeNamespace bool, includeKind bool) []string
|
||||||
headers(includeNamespace bool) []string
|
headers(includeNamespace bool) []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,11 +65,17 @@ func statusAndMessage(conditions []metav1.Condition) (string, string) {
|
|||||||
return string(metav1.ConditionFalse), "waiting to be reconciled"
|
return string(metav1.ConditionFalse), "waiting to be reconciled"
|
||||||
}
|
}
|
||||||
|
|
||||||
func nameColumns(item named, includeNamespace bool) []string {
|
func nameColumns(item named, includeNamespace bool, includeKind bool) []string {
|
||||||
if includeNamespace {
|
name := item.GetName()
|
||||||
return []string{item.GetNamespace(), item.GetName()}
|
if includeKind {
|
||||||
|
name = fmt.Sprintf("%s/%s",
|
||||||
|
strings.ToLower(item.GetObjectKind().GroupVersionKind().Kind),
|
||||||
|
item.GetName())
|
||||||
}
|
}
|
||||||
return []string{item.GetName()}
|
if includeNamespace {
|
||||||
|
return []string{item.GetNamespace(), name}
|
||||||
|
}
|
||||||
|
return []string{name}
|
||||||
}
|
}
|
||||||
|
|
||||||
var namespaceHeader = []string{"Namespace"}
|
var namespaceHeader = []string{"Namespace"}
|
||||||
@@ -100,17 +108,25 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAll := cmd.Use == "all"
|
||||||
|
|
||||||
if get.list.len() == 0 {
|
if get.list.len() == 0 {
|
||||||
logger.Failuref("no %s objects found in %s namespace", get.kind, rootArgs.namespace)
|
if !getAll {
|
||||||
|
logger.Failuref("no %s objects found in %s namespace", get.kind, rootArgs.namespace)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
header := get.list.headers(getArgs.allNamespaces)
|
header := get.list.headers(getArgs.allNamespaces)
|
||||||
var rows [][]string
|
var rows [][]string
|
||||||
for i := 0; i < get.list.len(); i++ {
|
for i := 0; i < get.list.len(); i++ {
|
||||||
row := get.list.summariseItem(i, getArgs.allNamespaces)
|
row := get.list.summariseItem(i, getArgs.allNamespaces, getAll)
|
||||||
rows = append(rows, row)
|
rows = append(rows, row)
|
||||||
}
|
}
|
||||||
utils.PrintTable(os.Stdout, header, rows)
|
utils.PrintTable(os.Stdout, header, rows)
|
||||||
|
|
||||||
|
if getAll {
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ func init() {
|
|||||||
getCmd.AddCommand(getHelmReleaseCmd)
|
getCmd.AddCommand(getHelmReleaseCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a helmReleaseListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (a helmReleaseListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := a.Items[i]
|
item := a.Items[i]
|
||||||
revision := item.Status.LastAppliedRevision
|
revision := item.Status.LastAppliedRevision
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
return append(nameColumns(&item, includeNamespace),
|
return append(nameColumns(&item, includeNamespace, includeKind),
|
||||||
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
66
cmd/flux/get_image_all.go
Normal file
66
cmd/flux/get_image_all.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
autov1 "github.com/fluxcd/image-automation-controller/api/v1alpha1"
|
||||||
|
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var getImageAllCmd = &cobra.Command{
|
||||||
|
Use: "all",
|
||||||
|
Short: "Get all image statuses",
|
||||||
|
Long: "The get image sub-commands print the statuses of all image objects.",
|
||||||
|
Example: ` # List all image objects in a namespace
|
||||||
|
flux get images all --namespace=flux-system
|
||||||
|
|
||||||
|
# List all image objects in all namespaces
|
||||||
|
flux get images all --all-namespaces
|
||||||
|
`,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
c := getCommand{
|
||||||
|
apiType: imageRepositoryType,
|
||||||
|
list: imageRepositoryListAdapter{&imagev1.ImageRepositoryList{}},
|
||||||
|
}
|
||||||
|
if err := c.run(cmd, args); err != nil {
|
||||||
|
logger.Failuref(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
c = getCommand{
|
||||||
|
apiType: imagePolicyType,
|
||||||
|
list: &imagePolicyListAdapter{&imagev1.ImagePolicyList{}},
|
||||||
|
}
|
||||||
|
if err := c.run(cmd, args); err != nil {
|
||||||
|
logger.Failuref(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
c = getCommand{
|
||||||
|
apiType: imageUpdateAutomationType,
|
||||||
|
list: &imageUpdateAutomationListAdapter{&autov1.ImageUpdateAutomationList{}},
|
||||||
|
}
|
||||||
|
if err := c.run(cmd, args); err != nil {
|
||||||
|
logger.Failuref(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
getImageCmd.AddCommand(getImageAllCmd)
|
||||||
|
}
|
||||||
@@ -42,10 +42,10 @@ func init() {
|
|||||||
getImageCmd.AddCommand(getImagePolicyCmd)
|
getImageCmd.AddCommand(getImagePolicyCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s imagePolicyListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (s imagePolicyListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := s.Items[i]
|
item := s.Items[i]
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
return append(nameColumns(&item, includeNamespace), status, msg, item.Status.LatestImage)
|
return append(nameColumns(&item, includeNamespace, includeKind), status, msg, item.Status.LatestImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s imagePolicyListAdapter) headers(includeNamespace bool) []string {
|
func (s imagePolicyListAdapter) headers(includeNamespace bool) []string {
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ func init() {
|
|||||||
getImageCmd.AddCommand(getImageRepositoryCmd)
|
getImageCmd.AddCommand(getImageRepositoryCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s imageRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (s imageRepositoryListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := s.Items[i]
|
item := s.Items[i]
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
var lastScan string
|
var lastScan string
|
||||||
if item.Status.LastScanResult != nil {
|
if item.Status.LastScanResult != nil {
|
||||||
lastScan = item.Status.LastScanResult.ScanTime.Time.Format(time.RFC3339)
|
lastScan = item.Status.LastScanResult.ScanTime.Time.Format(time.RFC3339)
|
||||||
}
|
}
|
||||||
return append(nameColumns(&item, includeNamespace),
|
return append(nameColumns(&item, includeNamespace, includeKind),
|
||||||
status, msg, lastScan, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
status, msg, lastScan, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ func init() {
|
|||||||
getImageCmd.AddCommand(getImageUpdateCmd)
|
getImageCmd.AddCommand(getImageUpdateCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s imageUpdateAutomationListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (s imageUpdateAutomationListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := s.Items[i]
|
item := s.Items[i]
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
var lastRun string
|
var lastRun string
|
||||||
if item.Status.LastAutomationRunTime != nil {
|
if item.Status.LastAutomationRunTime != nil {
|
||||||
lastRun = item.Status.LastAutomationRunTime.Time.Format(time.RFC3339)
|
lastRun = item.Status.LastAutomationRunTime.Time.Format(time.RFC3339)
|
||||||
}
|
}
|
||||||
return append(nameColumns(&item, includeNamespace), status, msg, lastRun, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
return append(nameColumns(&item, includeNamespace, includeKind), status, msg, lastRun, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s imageUpdateAutomationListAdapter) headers(includeNamespace bool) []string {
|
func (s imageUpdateAutomationListAdapter) headers(includeNamespace bool) []string {
|
||||||
@@ -42,11 +42,11 @@ func init() {
|
|||||||
getCmd.AddCommand(getKsCmd)
|
getCmd.AddCommand(getKsCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a kustomizationListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (a kustomizationListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := a.Items[i]
|
item := a.Items[i]
|
||||||
revision := item.Status.LastAppliedRevision
|
revision := item.Status.LastAppliedRevision
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
return append(nameColumns(&item, includeNamespace),
|
return append(nameColumns(&item, includeNamespace, includeKind),
|
||||||
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ func getReceiverCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
var rows [][]string
|
var rows [][]string
|
||||||
for _, receiver := range list.Items {
|
for _, receiver := range list.Items {
|
||||||
row := []string{}
|
var row []string
|
||||||
if c := apimeta.FindStatusCondition(receiver.Status.Conditions, meta.ReadyCondition); c != nil {
|
if c := apimeta.FindStatusCondition(receiver.Status.Conditions, meta.ReadyCondition); c != nil {
|
||||||
row = []string{
|
row = []string{
|
||||||
receiver.GetName(),
|
receiver.GetName(),
|
||||||
|
|||||||
73
cmd/flux/get_source_all.go
Normal file
73
cmd/flux/get_source_all.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var getSourceAllCmd = &cobra.Command{
|
||||||
|
Use: "all",
|
||||||
|
Short: "Get all source statuses",
|
||||||
|
Long: "The get sources all command print the statuses of all sources.",
|
||||||
|
Example: ` # List all sources in a namespace
|
||||||
|
flux get sources all --namespace=flux-system
|
||||||
|
|
||||||
|
# List all sources in all namespaces
|
||||||
|
flux get sources all --all-namespaces
|
||||||
|
`,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
c := getCommand{
|
||||||
|
apiType: bucketType,
|
||||||
|
list: &bucketListAdapter{&sourcev1.BucketList{}},
|
||||||
|
}
|
||||||
|
if err := c.run(cmd, args); err != nil {
|
||||||
|
logger.Failuref(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
c = getCommand{
|
||||||
|
apiType: gitRepositoryType,
|
||||||
|
list: &gitRepositoryListAdapter{&sourcev1.GitRepositoryList{}},
|
||||||
|
}
|
||||||
|
if err := c.run(cmd, args); err != nil {
|
||||||
|
logger.Failuref(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
c = getCommand{
|
||||||
|
apiType: helmRepositoryType,
|
||||||
|
list: &helmRepositoryListAdapter{&sourcev1.HelmRepositoryList{}},
|
||||||
|
}
|
||||||
|
if err := c.run(cmd, args); err != nil {
|
||||||
|
logger.Failuref(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
c = getCommand{
|
||||||
|
apiType: helmChartType,
|
||||||
|
list: &helmChartListAdapter{&sourcev1.HelmChartList{}},
|
||||||
|
}
|
||||||
|
if err := c.run(cmd, args); err != nil {
|
||||||
|
logger.Failuref(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
getSourceCmd.AddCommand(getSourceAllCmd)
|
||||||
|
}
|
||||||
@@ -44,14 +44,14 @@ func init() {
|
|||||||
getSourceCmd.AddCommand(getSourceBucketCmd)
|
getSourceCmd.AddCommand(getSourceBucketCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *bucketListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (a *bucketListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := a.Items[i]
|
item := a.Items[i]
|
||||||
var revision string
|
var revision string
|
||||||
if item.GetArtifact() != nil {
|
if item.GetArtifact() != nil {
|
||||||
revision = item.GetArtifact().Revision
|
revision = item.GetArtifact().Revision
|
||||||
}
|
}
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
return append(nameColumns(&item, includeNamespace),
|
return append(nameColumns(&item, includeNamespace, includeKind),
|
||||||
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ func init() {
|
|||||||
getSourceCmd.AddCommand(getSourceHelmChartCmd)
|
getSourceCmd.AddCommand(getSourceHelmChartCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *helmChartListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (a *helmChartListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := a.Items[i]
|
item := a.Items[i]
|
||||||
var revision string
|
var revision string
|
||||||
if item.GetArtifact() != nil {
|
if item.GetArtifact() != nil {
|
||||||
revision = item.GetArtifact().Revision
|
revision = item.GetArtifact().Revision
|
||||||
}
|
}
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
return append(nameColumns(&item, includeNamespace),
|
return append(nameColumns(&item, includeNamespace, includeKind),
|
||||||
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ func init() {
|
|||||||
getSourceCmd.AddCommand(getSourceGitCmd)
|
getSourceCmd.AddCommand(getSourceGitCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *gitRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (a *gitRepositoryListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := a.Items[i]
|
item := a.Items[i]
|
||||||
var revision string
|
var revision string
|
||||||
if item.GetArtifact() != nil {
|
if item.GetArtifact() != nil {
|
||||||
revision = item.GetArtifact().Revision
|
revision = item.GetArtifact().Revision
|
||||||
}
|
}
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
return append(nameColumns(&item, includeNamespace),
|
return append(nameColumns(&item, includeNamespace, includeKind),
|
||||||
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ func init() {
|
|||||||
getSourceCmd.AddCommand(getSourceHelmCmd)
|
getSourceCmd.AddCommand(getSourceHelmCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
|
func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string {
|
||||||
item := a.Items[i]
|
item := a.Items[i]
|
||||||
var revision string
|
var revision string
|
||||||
if item.GetArtifact() != nil {
|
if item.GetArtifact() != nil {
|
||||||
revision = item.GetArtifact().Revision
|
revision = item.GetArtifact().Revision
|
||||||
}
|
}
|
||||||
status, msg := statusAndMessage(item.Status.Conditions)
|
status, msg := statusAndMessage(item.Status.Conditions)
|
||||||
return append(nameColumns(&item, includeNamespace),
|
return append(nameColumns(&item, includeNamespace, includeKind),
|
||||||
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/fluxcd/flux2/internal/flags"
|
"github.com/fluxcd/flux2/internal/flags"
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
"github.com/fluxcd/flux2/pkg/manifestgen/install"
|
||||||
|
"github.com/fluxcd/flux2/pkg/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
var installCmd = &cobra.Command{
|
var installCmd = &cobra.Command{
|
||||||
@@ -200,7 +201,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
applyOutput = utils.ModeOS
|
applyOutput = utils.ModeOS
|
||||||
}
|
}
|
||||||
if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if installArgs.dryRun {
|
if installArgs.dryRun {
|
||||||
@@ -208,13 +209,20 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
statusChecker, err := NewStatusChecker(time.Second, time.Minute)
|
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
statusChecker, err := status.NewStatusChecker(kubeConfig, time.Second, rootArgs.timeout, logger)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("install failed: %w", err)
|
||||||
|
}
|
||||||
|
componentRefs, err := buildComponentObjectRefs(components...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("install failed: %w", err)
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Waitingf("verifying installation")
|
logger.Waitingf("verifying installation")
|
||||||
if err := statusChecker.Assess(components...); err != nil {
|
if err := statusChecker.Assess(componentRefs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
261
cmd/flux/logs.go
Normal file
261
cmd/flux/logs.go
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
|
||||||
|
"github.com/fluxcd/flux2/internal/flags"
|
||||||
|
"github.com/fluxcd/flux2/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logsCmd = &cobra.Command{
|
||||||
|
Use: "logs",
|
||||||
|
Short: "Display formatted logs for Flux components",
|
||||||
|
Long: "The logs command displays formatted logs from various Flux components.",
|
||||||
|
Example: ` # Print the reconciliation logs of all Flux custom resources in your cluster
|
||||||
|
flux logs --all-namespaces
|
||||||
|
|
||||||
|
# Stream logs for a particular log level
|
||||||
|
flux logs --follow --level=error --all-namespaces
|
||||||
|
|
||||||
|
# Filter logs by kind, name and namespace
|
||||||
|
flux logs --kind=Kustomization --name=podinfo --namespace=default
|
||||||
|
|
||||||
|
# Print logs when Flux is installed in a different namespace than flux-system
|
||||||
|
flux logs --flux-namespace=my-namespace
|
||||||
|
`,
|
||||||
|
RunE: logsCmdRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
type logsFlags struct {
|
||||||
|
logLevel flags.LogLevel
|
||||||
|
follow bool
|
||||||
|
tail int64
|
||||||
|
kind string
|
||||||
|
name string
|
||||||
|
fluxNamespace string
|
||||||
|
allNamespaces bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var logsArgs = &logsFlags{
|
||||||
|
tail: -1,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
logsCmd.Flags().Var(&logsArgs.logLevel, "level", logsArgs.logLevel.Description())
|
||||||
|
logsCmd.Flags().StringVarP(&logsArgs.kind, "kind", "", logsArgs.kind, "displays errors of a particular toolkit kind e.g GitRepository")
|
||||||
|
logsCmd.Flags().StringVarP(&logsArgs.name, "name", "", logsArgs.name, "specifies the name of the object logs to be displayed")
|
||||||
|
logsCmd.Flags().BoolVarP(&logsArgs.follow, "follow", "f", logsArgs.follow, "specifies if the logs should be streamed")
|
||||||
|
logsCmd.Flags().Int64VarP(&logsArgs.tail, "tail", "", logsArgs.tail, "lines of recent log file to display")
|
||||||
|
logsCmd.Flags().StringVarP(&logsArgs.fluxNamespace, "flux-namespace", "", rootArgs.defaults.Namespace, "the namespace where the Flux components are running")
|
||||||
|
logsCmd.Flags().BoolVarP(&logsArgs.allNamespaces, "all-namespaces", "A", false, "displays logs for objects across all namespaces")
|
||||||
|
rootCmd.AddCommand(logsCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func logsCmdRun(cmd *cobra.Command, args []string) error {
|
||||||
|
fluxSelector := fmt.Sprintf("app.kubernetes.io/instance=%s", logsArgs.fluxNamespace)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var pods []corev1.Pod
|
||||||
|
cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
clientset, err := kubernetes.NewForConfig(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
return fmt.Errorf("no argument required")
|
||||||
|
}
|
||||||
|
|
||||||
|
pods, err = getPods(ctx, clientset, fluxSelector)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logOpts := &corev1.PodLogOptions{
|
||||||
|
Follow: logsArgs.follow,
|
||||||
|
}
|
||||||
|
|
||||||
|
if logsArgs.tail > -1 {
|
||||||
|
logOpts.TailLines = &logsArgs.tail
|
||||||
|
}
|
||||||
|
|
||||||
|
var requests []rest.ResponseWrapper
|
||||||
|
for _, pod := range pods {
|
||||||
|
req := clientset.CoreV1().Pods(logsArgs.fluxNamespace).GetLogs(pod.Name, logOpts)
|
||||||
|
requests = append(requests, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
if logsArgs.follow && len(requests) > 1 {
|
||||||
|
return parallelPodLogs(ctx, requests)
|
||||||
|
}
|
||||||
|
|
||||||
|
return podLogs(ctx, requests)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPods(ctx context.Context, c *kubernetes.Clientset, label string) ([]corev1.Pod, error) {
|
||||||
|
var ret []corev1.Pod
|
||||||
|
|
||||||
|
opts := metav1.ListOptions{
|
||||||
|
LabelSelector: label,
|
||||||
|
}
|
||||||
|
deployList, err := c.AppsV1().Deployments(logsArgs.fluxNamespace).List(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, deploy := range deployList.Items {
|
||||||
|
label := deploy.Spec.Template.Labels
|
||||||
|
opts := metav1.ListOptions{
|
||||||
|
LabelSelector: createLabelStringFromMap(label),
|
||||||
|
}
|
||||||
|
podList, err := c.CoreV1().Pods(logsArgs.fluxNamespace).List(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
ret = append(ret, podList.Items...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parallelPodLogs(ctx context.Context, requests []rest.ResponseWrapper) error {
|
||||||
|
reader, writer := io.Pipe()
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(len(requests))
|
||||||
|
|
||||||
|
var mutex = &sync.Mutex{}
|
||||||
|
|
||||||
|
for _, request := range requests {
|
||||||
|
go func(req rest.ResponseWrapper) {
|
||||||
|
defer wg.Done()
|
||||||
|
if err := logRequest(mutex, ctx, req, os.Stdout); err != nil {
|
||||||
|
writer.CloseWithError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
wg.Wait()
|
||||||
|
writer.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err := io.Copy(os.Stdout, reader)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func podLogs(ctx context.Context, requests []rest.ResponseWrapper) error {
|
||||||
|
mutex := &sync.Mutex{}
|
||||||
|
for _, req := range requests {
|
||||||
|
if err := logRequest(mutex, ctx, req, os.Stdout); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createLabelStringFromMap(m map[string]string) string {
|
||||||
|
var strArr []string
|
||||||
|
for key, val := range m {
|
||||||
|
pair := fmt.Sprintf("%v=%v", key, val)
|
||||||
|
strArr = append(strArr, pair)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(strArr, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func logRequest(mu *sync.Mutex, ctx context.Context, request rest.ResponseWrapper, w io.Writer) error {
|
||||||
|
stream, err := request.Stream(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer stream.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(stream)
|
||||||
|
|
||||||
|
const logTmpl = "{{.Timestamp}} {{.Level}} {{.Kind}}{{if .Name}}/{{.Name}}.{{.Namespace}}{{end}} - {{.Message}} {{.Error}}\n"
|
||||||
|
t, err := template.New("log").Parse(logTmpl)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to create template, err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if !strings.HasPrefix(line, "{") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var l ControllerLogEntry
|
||||||
|
if err := json.Unmarshal([]byte(line), &l); err != nil {
|
||||||
|
logger.Failuref("parse error: %s", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
mu.Lock()
|
||||||
|
filterPrintLog(t, &l)
|
||||||
|
mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := t.Execute(os.Stdout, l)
|
||||||
|
if err != nil {
|
||||||
|
logger.Failuref("log template error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ControllerLogEntry struct {
|
||||||
|
Timestamp string `json:"ts"`
|
||||||
|
Level flags.LogLevel `json:"level"`
|
||||||
|
Message string `json:"msg"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
Logger string `json:"logger"`
|
||||||
|
Kind string `json:"reconciler kind,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Namespace string `json:"namespace,omitempty"`
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ func (c universalAdapter) asClientObject() client.Object {
|
|||||||
type named interface {
|
type named interface {
|
||||||
GetName() string
|
GetName() string
|
||||||
GetNamespace() string
|
GetNamespace() string
|
||||||
|
GetObjectKind() schema.ObjectKind
|
||||||
SetName(string)
|
SetName(string)
|
||||||
SetNamespace(string)
|
SetNamespace(string)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func (a helmChartAdapter) asClientObject() client.Object {
|
|||||||
return a.HelmChart
|
return a.HelmChart
|
||||||
}
|
}
|
||||||
|
|
||||||
// sourcev1.ImagePolicyList
|
// sourcev1.HelmChartList
|
||||||
|
|
||||||
type helmChartListAdapter struct {
|
type helmChartListAdapter struct {
|
||||||
*sourcev1.HelmChartList
|
*sourcev1.HelmChartList
|
||||||
|
|||||||
@@ -19,26 +19,16 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
|
||||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/aggregator"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
|
||||||
"sigs.k8s.io/cli-utils/pkg/object"
|
"sigs.k8s.io/cli-utils/pkg/object"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/apis/meta"
|
"github.com/fluxcd/pkg/apis/meta"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/internal/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// statusable is used to see if a resource is considered ready in the usual way
|
// statusable is used to see if a resource is considered ready in the usual way
|
||||||
@@ -51,13 +41,6 @@ type statusable interface {
|
|||||||
GetStatusConditions() *[]metav1.Condition
|
GetStatusConditions() *[]metav1.Condition
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusChecker struct {
|
|
||||||
pollInterval time.Duration
|
|
||||||
timeout time.Duration
|
|
||||||
client client.Client
|
|
||||||
statusPoller *polling.StatusPoller
|
|
||||||
}
|
|
||||||
|
|
||||||
func isReady(ctx context.Context, kubeClient client.Client,
|
func isReady(ctx context.Context, kubeClient client.Client,
|
||||||
namespacedName types.NamespacedName, object statusable) wait.ConditionFunc {
|
namespacedName types.NamespacedName, object statusable) wait.ConditionFunc {
|
||||||
return func() (bool, error) {
|
return func() (bool, error) {
|
||||||
@@ -83,74 +66,7 @@ func isReady(ctx context.Context, kubeClient client.Client,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStatusChecker(pollInterval time.Duration, timeout time.Duration) (*StatusChecker, error) {
|
func buildComponentObjectRefs(components ...string) ([]object.ObjMetadata, error) {
|
||||||
kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
restMapper, err := apiutil.NewDynamicRESTMapper(kubeConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
client, err := client.New(kubeConfig, client.Options{Mapper: restMapper})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &StatusChecker{
|
|
||||||
pollInterval: pollInterval,
|
|
||||||
timeout: timeout,
|
|
||||||
client: client,
|
|
||||||
statusPoller: polling.NewStatusPoller(client, restMapper),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *StatusChecker) Assess(components ...string) error {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
objRefs, err := sc.getObjectRefs(components)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := polling.Options{PollInterval: sc.pollInterval, UseCache: true}
|
|
||||||
eventsChan := sc.statusPoller.Poll(ctx, objRefs, opts)
|
|
||||||
|
|
||||||
coll := collector.NewResourceStatusCollector(objRefs)
|
|
||||||
done := coll.ListenWithObserver(eventsChan, collector.ObserverFunc(
|
|
||||||
func(statusCollector *collector.ResourceStatusCollector, e event.Event) {
|
|
||||||
var rss []*event.ResourceStatus
|
|
||||||
for _, rs := range statusCollector.ResourceStatuses {
|
|
||||||
rss = append(rss, rs)
|
|
||||||
}
|
|
||||||
desired := status.CurrentStatus
|
|
||||||
aggStatus := aggregator.AggregateStatus(rss, desired)
|
|
||||||
if aggStatus == desired {
|
|
||||||
cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
<-done
|
|
||||||
|
|
||||||
if coll.Error != nil || ctx.Err() == context.DeadlineExceeded {
|
|
||||||
for _, rs := range coll.ResourceStatuses {
|
|
||||||
if rs.Status != status.CurrentStatus {
|
|
||||||
if !sc.deploymentExists(rs.Identifier) {
|
|
||||||
logger.Failuref("%s: deployment not found", rs.Identifier.Name)
|
|
||||||
} else {
|
|
||||||
logger.Failuref("%s: unhealthy (timed out waiting for rollout)", rs.Identifier.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("timed out waiting for condition")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *StatusChecker) getObjectRefs(components []string) ([]object.ObjMetadata, error) {
|
|
||||||
var objRefs []object.ObjMetadata
|
var objRefs []object.ObjMetadata
|
||||||
for _, deployment := range components {
|
for _, deployment := range components {
|
||||||
objMeta, err := object.CreateObjMetadata(rootArgs.namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"})
|
objMeta, err := object.CreateObjMetadata(rootArgs.namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"})
|
||||||
@@ -161,20 +77,3 @@ func (sc *StatusChecker) getObjectRefs(components []string) ([]object.ObjMetadat
|
|||||||
}
|
}
|
||||||
return objRefs, nil
|
return objRefs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *StatusChecker) objMetadataToString(om object.ObjMetadata) string {
|
|
||||||
return fmt.Sprintf("%s '%s/%s'", om.GroupKind.Kind, om.Namespace, om.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *StatusChecker) deploymentExists(om object.ObjMetadata) bool {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
namespacedName := types.NamespacedName{
|
|
||||||
Namespace: om.Namespace,
|
|
||||||
Name: om.Name,
|
|
||||||
}
|
|
||||||
var existing appsv1.Deployment
|
|
||||||
err := sc.client.Get(ctx, namespacedName, &existing)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|||||||
BIN
docs/_files/image-update-automation.png
Normal file
BIN
docs/_files/image-update-automation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
27
docs/_static/custom.css
vendored
27
docs/_static/custom.css
vendored
@@ -94,4 +94,29 @@ body {
|
|||||||
|
|
||||||
.progress-0plus .progress-bar {
|
.progress-0plus .progress-bar {
|
||||||
background-color: #ff1744;
|
background-color: #ff1744;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Custom admonitions */
|
||||||
|
/* See https://squidfunk.github.io/mkdocs-material/reference/admonitions */
|
||||||
|
:root {
|
||||||
|
--md-admonition-icon--heart: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 20.408c-.492.308-.903.546-1.192.709-.153.086-.308.17-.463.252h-.002a.75.75 0 0 1-.686 0 16.709 16.709 0 0 1-.465-.252 31.147 31.147 0 0 1-4.803-3.34C3.8 15.572 1 12.331 1 8.513 1 5.052 3.829 2.5 6.736 2.5 9.03 2.5 10.881 3.726 12 5.605 13.12 3.726 14.97 2.5 17.264 2.5 20.17 2.5 23 5.052 23 8.514c0 3.818-2.801 7.06-5.389 9.262A31.146 31.146 0 0 1 14 20.408z"/></svg>')
|
||||||
|
}
|
||||||
|
.md-typeset .admonition.heart,
|
||||||
|
.md-typeset details.heart {
|
||||||
|
border-color: rgb(233, 30, 99);
|
||||||
|
}
|
||||||
|
.md-typeset .heart > .admonition-title,
|
||||||
|
.md-typeset .heart > summary {
|
||||||
|
background-color: rgba(233, 30, 99, 0.1);
|
||||||
|
}
|
||||||
|
.md-typeset .heart > .admonition-title::before,
|
||||||
|
.md-typeset .heart > summary::before {
|
||||||
|
background-color: rgb(233, 30, 99);
|
||||||
|
-webkit-mask-image: var(--md-admonition-icon--heart);
|
||||||
|
mask-image: var(--md-admonition-icon--heart);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timetable-explicit-col-widths th:nth-child(1) { width: 4%; }
|
||||||
|
.timetable-explicit-col-widths th:nth-child(2) { width: 32%; }
|
||||||
|
.timetable-explicit-col-widths th:nth-child(3) { width: 32%; }
|
||||||
|
.timetable-explicit-col-widths th:nth-child(4) { width: 32%; }
|
||||||
|
|||||||
@@ -83,8 +83,9 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
|
|||||||
* [flux create](flux_create.md) - Create or update sources and resources
|
* [flux create](flux_create.md) - Create or update sources and resources
|
||||||
* [flux delete](flux_delete.md) - Delete sources and resources
|
* [flux delete](flux_delete.md) - Delete sources and resources
|
||||||
* [flux export](flux_export.md) - Export resources in YAML format
|
* [flux export](flux_export.md) - Export resources in YAML format
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
* [flux install](flux_install.md) - Install or upgrade Flux
|
* [flux install](flux_install.md) - Install or upgrade Flux
|
||||||
|
* [flux logs](flux_logs.md) - Display formatted logs for Flux components
|
||||||
* [flux reconcile](flux_reconcile.md) - Reconcile sources and resources
|
* [flux reconcile](flux_reconcile.md) - Reconcile sources and resources
|
||||||
* [flux resume](flux_resume.md) - Resume suspended resources
|
* [flux resume](flux_resume.md) - Resume suspended resources
|
||||||
* [flux suspend](flux_suspend.md) - Suspend resources
|
* [flux suspend](flux_suspend.md) - Suspend resources
|
||||||
|
|||||||
@@ -12,7 +12,24 @@ The image that sorts highest according to the policy is recorded in
|
|||||||
the status of the object.
|
the status of the object.
|
||||||
|
|
||||||
```
|
```
|
||||||
flux create image policy <name> [flags]
|
flux create image policy [name] [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
# Create an ImagePolicy to select the latest stable release
|
||||||
|
flux create image policy podinfo \
|
||||||
|
--image-ref=podinfo \
|
||||||
|
--select-semver=">=1.0.0"
|
||||||
|
|
||||||
|
# Create an ImagePolicy to select the latest main branch build tagged as "${GIT_BRANCH}-${GIT_SHA:0:7}-$(date +%s)"
|
||||||
|
flux create image policy podinfo \
|
||||||
|
--image-ref=podinfo \
|
||||||
|
--select-numeric=asc \
|
||||||
|
--filter-regex='^main-[a-f0-9]+-(?P<ts>[0-9]+)' \
|
||||||
|
--filter-extract='$ts'
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ The create image repository command generates an ImageRepository resource.
|
|||||||
An ImageRepository object specifies an image repository to scan.
|
An ImageRepository object specifies an image repository to scan.
|
||||||
|
|
||||||
```
|
```
|
||||||
flux create image repository <name> [flags]
|
flux create image repository [name] [flags]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|||||||
@@ -9,7 +9,31 @@ An ImageUpdateAutomation object specifies an automated update to images
|
|||||||
mentioned in YAMLs in a git repository.
|
mentioned in YAMLs in a git repository.
|
||||||
|
|
||||||
```
|
```
|
||||||
flux create image update <name> [flags]
|
flux create image update [name] [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
# Configure image updates for the main repository created by flux bootstrap
|
||||||
|
flux create image update flux-system \
|
||||||
|
--git-repo-ref=flux-system \
|
||||||
|
--git-repo-path="./clusters/my-cluster" \
|
||||||
|
--checkout-branch=main \
|
||||||
|
--author-name=flux \
|
||||||
|
--author-email=flux@example.com \
|
||||||
|
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
|
||||||
|
|
||||||
|
# Configure image updates to push changes to a different branch, if the branch doesn't exists it will be created
|
||||||
|
flux create image update flux-system \
|
||||||
|
--git-repo-ref=flux-system \
|
||||||
|
--git-repo-path="./clusters/my-cluster" \
|
||||||
|
--checkout-branch=main \
|
||||||
|
--push-branch=image-updates \
|
||||||
|
--author-name=flux \
|
||||||
|
--author-email=flux@example.com \
|
||||||
|
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}"
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
@@ -17,10 +41,12 @@ flux create image update <name> [flags]
|
|||||||
```
|
```
|
||||||
--author-email string the email to use for commit author
|
--author-email string the email to use for commit author
|
||||||
--author-name string the name to use for commit author
|
--author-name string the name to use for commit author
|
||||||
--branch string the branch to checkout and push commits to
|
--checkout-branch string the branch to checkout
|
||||||
--commit-template string a template for commit messages
|
--commit-template string a template for commit messages
|
||||||
--git-repo-ref string the name of a GitRepository resource with details of the upstream git repository
|
--git-repo-path string path to the directory containing the manifests to be updated, defaults to the repository root
|
||||||
|
--git-repo-ref string the name of a GitRepository resource with details of the upstream Git repository
|
||||||
-h, --help help for update
|
-h, --help help for update
|
||||||
|
--push-branch string the branch to push commits to, defaults to the checkout branch if not specified
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options inherited from parent commands
|
### Options inherited from parent commands
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Export Bucket sources in YAML format
|
|||||||
|
|
||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
The export source git command exports on or all Bucket sources in YAML format.
|
The export source git command exports one or all Bucket sources in YAML format.
|
||||||
|
|
||||||
```
|
```
|
||||||
flux export source bucket [name] [flags]
|
flux export source bucket [name] [flags]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Export GitRepository sources in YAML format
|
|||||||
|
|
||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
The export source git command exports on or all GitRepository sources in YAML format.
|
The export source git command exports one or all GitRepository sources in YAML format.
|
||||||
|
|
||||||
```
|
```
|
||||||
flux export source git [name] [flags]
|
flux export source git [name] [flags]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Export HelmRepository sources in YAML format
|
|||||||
|
|
||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
The export source git command exports on or all HelmRepository sources in YAML format.
|
The export source git command exports one or all HelmRepository sources in YAML format.
|
||||||
|
|
||||||
```
|
```
|
||||||
flux export source helm [name] [flags]
|
flux export source helm [name] [flags]
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
## flux get
|
## flux get
|
||||||
|
|
||||||
Get sources and resources
|
Get the resources and their status
|
||||||
|
|
||||||
### Synopsis
|
### Synopsis
|
||||||
|
|
||||||
The get sub-commands print the statuses of sources and resources.
|
The get sub-commands print the statuses of Flux resources.
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
|||||||
@@ -37,5 +37,5 @@ flux get alert-providers [flags]
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
|
|
||||||
|
|||||||
@@ -37,5 +37,5 @@ flux get alerts [flags]
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
|
|
||||||
|
|||||||
@@ -37,5 +37,5 @@ flux get helmreleases [flags]
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ The get image sub-commands print the status of image automation objects.
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
|
* [flux get images all](flux_get_images_all.md) - Get all image statuses
|
||||||
* [flux get images policy](flux_get_images_policy.md) - Get ImagePolicy status
|
* [flux get images policy](flux_get_images_policy.md) - Get ImagePolicy status
|
||||||
* [flux get images repository](flux_get_images_repository.md) - Get ImageRepository status
|
* [flux get images repository](flux_get_images_repository.md) - Get ImageRepository status
|
||||||
* [flux get images update](flux_get_images_update.md) - Get ImageUpdateAutomation status
|
* [flux get images update](flux_get_images_update.md) - Get ImageUpdateAutomation status
|
||||||
|
|||||||
44
docs/cmd/flux_get_images_all.md
Normal file
44
docs/cmd/flux_get_images_all.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
## flux get images all
|
||||||
|
|
||||||
|
Get all image statuses
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
The get image sub-commands print the statuses of all image objects.
|
||||||
|
|
||||||
|
```
|
||||||
|
flux get images all [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
# List all image objects in a namespace
|
||||||
|
flux get images all --namespace=flux-system
|
||||||
|
|
||||||
|
# List all image objects in all namespaces
|
||||||
|
flux get images all --all-namespaces
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for all
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options inherited from parent commands
|
||||||
|
|
||||||
|
```
|
||||||
|
-A, --all-namespaces list the requested object(s) across all namespaces
|
||||||
|
--context string kubernetes context to use
|
||||||
|
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||||
|
-n, --namespace string the namespace scope for this operation (default "flux-system")
|
||||||
|
--timeout duration timeout for this operation (default 5m0s)
|
||||||
|
--verbose print generated objects
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [flux get images](flux_get_images.md) - Get image automation object status
|
||||||
|
|
||||||
@@ -37,5 +37,5 @@ flux get kustomizations [flags]
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
|
|
||||||
|
|||||||
@@ -37,5 +37,5 @@ flux get receivers [flags]
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ The get source sub-commands print the statuses of the sources.
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
* [flux get](flux_get.md) - Get sources and resources
|
* [flux get](flux_get.md) - Get the resources and their status
|
||||||
|
* [flux get sources all](flux_get_sources_all.md) - Get all source statuses
|
||||||
* [flux get sources bucket](flux_get_sources_bucket.md) - Get Bucket source statuses
|
* [flux get sources bucket](flux_get_sources_bucket.md) - Get Bucket source statuses
|
||||||
* [flux get sources chart](flux_get_sources_chart.md) - Get HelmChart statuses
|
* [flux get sources chart](flux_get_sources_chart.md) - Get HelmChart statuses
|
||||||
* [flux get sources git](flux_get_sources_git.md) - Get GitRepository source statuses
|
* [flux get sources git](flux_get_sources_git.md) - Get GitRepository source statuses
|
||||||
|
|||||||
44
docs/cmd/flux_get_sources_all.md
Normal file
44
docs/cmd/flux_get_sources_all.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
## flux get sources all
|
||||||
|
|
||||||
|
Get all source statuses
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
The get sources all command print the statuses of all sources.
|
||||||
|
|
||||||
|
```
|
||||||
|
flux get sources all [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
# List all sources in a namespace
|
||||||
|
flux get sources all --namespace=flux-system
|
||||||
|
|
||||||
|
# List all sources in all namespaces
|
||||||
|
flux get sources all --all-namespaces
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help help for all
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options inherited from parent commands
|
||||||
|
|
||||||
|
```
|
||||||
|
-A, --all-namespaces list the requested object(s) across all namespaces
|
||||||
|
--context string kubernetes context to use
|
||||||
|
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||||
|
-n, --namespace string the namespace scope for this operation (default "flux-system")
|
||||||
|
--timeout duration timeout for this operation (default 5m0s)
|
||||||
|
--verbose print generated objects
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [flux get sources](flux_get_sources.md) - Get source statuses
|
||||||
|
|
||||||
56
docs/cmd/flux_logs.md
Normal file
56
docs/cmd/flux_logs.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
## flux logs
|
||||||
|
|
||||||
|
Display formatted logs for Flux components
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
The logs command displays formatted logs from various Flux components.
|
||||||
|
|
||||||
|
```
|
||||||
|
flux logs [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
# Print the reconciliation logs of all Flux custom resources in your cluster
|
||||||
|
flux logs --all-namespaces
|
||||||
|
|
||||||
|
# Stream logs for a particular log level
|
||||||
|
flux logs --follow --level=error --all-namespaces
|
||||||
|
|
||||||
|
# Filter logs by kind, name and namespace
|
||||||
|
flux logs --kind=Kustomization --name=podinfo --namespace=default
|
||||||
|
|
||||||
|
# Print logs when Flux is installed in a different namespace than flux-system
|
||||||
|
flux logs --flux-namespace=my-namespace
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-A, --all-namespaces displays logs for objects across all namespaces
|
||||||
|
--flux-namespace string the namespace where the Flux components are running (default "flux-system")
|
||||||
|
-f, --follow specifies if the logs should be streamed
|
||||||
|
-h, --help help for logs
|
||||||
|
--kind string displays errors of a particular toolkit kind e.g GitRepository
|
||||||
|
--level logLevel log level, available options are: (debug, info, error)
|
||||||
|
--name string specifies the name of the object logs to be displayed
|
||||||
|
--tail int lines of recent log file to display (default -1)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options inherited from parent commands
|
||||||
|
|
||||||
|
```
|
||||||
|
--context string kubernetes context to use
|
||||||
|
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||||
|
-n, --namespace string the namespace scope for this operation (default "flux-system")
|
||||||
|
--timeout duration timeout for this operation (default 5m0s)
|
||||||
|
--verbose print generated objects
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [flux](flux.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||||
|
|
||||||
@@ -8,6 +8,8 @@ repository when new container images are available.
|
|||||||
- The image-automation-controller updates YAML files based on the latest images scanned, and commits
|
- The image-automation-controller updates YAML files based on the latest images scanned, and commits
|
||||||
the changes to a given Git repository.
|
the changes to a given Git repository.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
Links:
|
Links:
|
||||||
|
|
||||||
- Source code [fluxcd/image-reflector-controller](https://github.com/fluxcd/image-reflector-controller)
|
- Source code [fluxcd/image-reflector-controller](https://github.com/fluxcd/image-reflector-controller)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ is produced.
|
|||||||
All sources are specified as Custom Resources in a Kubernetes cluster, examples
|
All sources are specified as Custom Resources in a Kubernetes cluster, examples
|
||||||
of sources are `GitRepository`, `HelmRepository` and `Bucket` resources.
|
of sources are `GitRepository`, `HelmRepository` and `Bucket` resources.
|
||||||
|
|
||||||
For more information, take a look at [the source controller documentation](../components/source/source.md).
|
For more information, take a look at [the source controller documentation](../components/source/controller.md).
|
||||||
|
|
||||||
## Reconciliation
|
## Reconciliation
|
||||||
|
|
||||||
|
|||||||
@@ -431,8 +431,8 @@ spec:
|
|||||||
```
|
```
|
||||||
|
|
||||||
!!! hint
|
!!! hint
|
||||||
If you are using the same image repository in several manifests, you only need one
|
If you are using the same image repository in several manifests, you only need one
|
||||||
`ImageRepository` object for it.
|
`ImageRepository` object for it.
|
||||||
|
|
||||||
##### Using image registry credentials for scanning
|
##### Using image registry credentials for scanning
|
||||||
|
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ podinfo True Latest image tag for 'ghcr.io/stefanprodan/podinfo' resolved to: 5
|
|||||||
|
|
||||||
## Configure image updates
|
## Configure image updates
|
||||||
|
|
||||||
Edit the `podinfo-deploy.yaml` and add a marker to tell Flux which policy to use when updating the container image:
|
Edit the `podinfo-deployment.yaml` and add a marker to tell Flux which policy to use when updating the container image:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
spec:
|
spec:
|
||||||
@@ -247,9 +247,12 @@ Create an `ImageUpdateAutomation` to tell Flux which Git repository to write ima
|
|||||||
flux create image update flux-system \
|
flux create image update flux-system \
|
||||||
--git-repo-ref=flux-system \
|
--git-repo-ref=flux-system \
|
||||||
--branch=main \
|
--branch=main \
|
||||||
|
--git-repo-path="./clusters/my-cluster" \
|
||||||
|
--checkout-branch=main \
|
||||||
|
--push-branch=main \
|
||||||
--author-name=fluxcdbot \
|
--author-name=fluxcdbot \
|
||||||
--author-email=fluxcdbot@users.noreply.github.com \
|
--author-email=fluxcdbot@users.noreply.github.com \
|
||||||
--commit-template="[ci skip] update image" \
|
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}" \
|
||||||
--export > ./clusters/my-cluster/flux-system-automation.yaml
|
--export > ./clusters/my-cluster/flux-system-automation.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -269,9 +272,12 @@ spec:
|
|||||||
commit:
|
commit:
|
||||||
authorEmail: fluxcdbot@users.noreply.github.com
|
authorEmail: fluxcdbot@users.noreply.github.com
|
||||||
authorName: fluxcdbot
|
authorName: fluxcdbot
|
||||||
messageTemplate: '[ci skip] update image'
|
messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
|
||||||
interval: 1m0s
|
interval: 1m0s
|
||||||
|
push:
|
||||||
|
branch: main
|
||||||
update:
|
update:
|
||||||
|
path: ./clusters/my-cluster
|
||||||
strategy: Setters
|
strategy: Setters
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -306,6 +312,12 @@ $ watch "kubectl get deployment/podinfo -oyaml | grep 'image:'"
|
|||||||
image: ghcr.io/stefanprodan/podinfo:5.0.3
|
image: ghcr.io/stefanprodan/podinfo:5.0.3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can check the status of the image automation objects with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flux get images all --all-namespaces
|
||||||
|
```
|
||||||
|
|
||||||
## Configure image update for custom resources
|
## Configure image update for custom resources
|
||||||
|
|
||||||
Besides Kubernetes native kinds (Deployment, StatefulSet, DaemonSet, CronJob),
|
Besides Kubernetes native kinds (Deployment, StatefulSet, DaemonSet, CronJob),
|
||||||
@@ -374,6 +386,68 @@ images:
|
|||||||
newTag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo:tag"}
|
newTag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo:tag"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Push updates to a different branch
|
||||||
|
|
||||||
|
With `.spec.push.branch` you can configure Flux to push the image updates to different branch
|
||||||
|
than the one used for checkout. If the specified branch doesn't exist, Flux will create it for you.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: image.toolkit.fluxcd.io/v1alpha1
|
||||||
|
kind: ImageUpdateAutomation
|
||||||
|
metadata:
|
||||||
|
name: flux-system
|
||||||
|
spec:
|
||||||
|
checkout:
|
||||||
|
branch: main
|
||||||
|
gitRepositoryRef:
|
||||||
|
name: flux-system
|
||||||
|
push:
|
||||||
|
branch: image-updates
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use CI automation e.g. GitHub Actions such as
|
||||||
|
[create-pull-request](https://github.com/peter-evans/create-pull-request)
|
||||||
|
to open a pull request against the checkout branch.
|
||||||
|
|
||||||
|
This way you can manually approve the image updates before they are applied on your clusters.
|
||||||
|
|
||||||
|
## Configure the commit message
|
||||||
|
|
||||||
|
The `.spec.commit.messageTemplate` field is a string which is used as a template for the commit message.
|
||||||
|
|
||||||
|
The message template is a [Go text template](https://golang.org/pkg/text/template/) that
|
||||||
|
lets you range over the objects and images e.g.:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: image.toolkit.fluxcd.io/v1alpha1
|
||||||
|
kind: ImageUpdateAutomation
|
||||||
|
metadata:
|
||||||
|
name: flux-system
|
||||||
|
spec:
|
||||||
|
commit:
|
||||||
|
messsageTemplate: |
|
||||||
|
Automated image update
|
||||||
|
|
||||||
|
Automation name: {{ .AutomationObject }}
|
||||||
|
|
||||||
|
Files:
|
||||||
|
{{ range $filename, $_ := .Updated.Files -}}
|
||||||
|
- {{ $filename }}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Objects:
|
||||||
|
{{ range $resource, $_ := .Updated.Objects -}}
|
||||||
|
- {{ $resource.Kind }} {{ $resource.Name }}
|
||||||
|
{{ end -}}
|
||||||
|
|
||||||
|
Images:
|
||||||
|
{{ range .Updated.Images -}}
|
||||||
|
- {{.}}
|
||||||
|
{{ end -}}
|
||||||
|
authorEmail: flux@example.com
|
||||||
|
authorName: flux
|
||||||
|
```
|
||||||
|
|
||||||
## Trigger image updates with webhooks
|
## Trigger image updates with webhooks
|
||||||
|
|
||||||
You may want to trigger a deployment
|
You may want to trigger a deployment
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ toolkit controllers installed on it.
|
|||||||
Please see the [get started guide](../get-started/index.md)
|
Please see the [get started guide](../get-started/index.md)
|
||||||
or the [installation guide](installation.md).
|
or the [installation guide](installation.md).
|
||||||
|
|
||||||
Install [gnupg](https://www.gnupg.org/) and [sops](https://github.com/mozilla/sops):
|
Install [gnupg](https://www.gnupg.org/) and [SOPS](https://github.com/mozilla/sops):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
brew install gnupg sops
|
brew install gnupg sops
|
||||||
@@ -19,38 +19,144 @@ brew install gnupg sops
|
|||||||
|
|
||||||
## Generate a GPG key
|
## Generate a GPG key
|
||||||
|
|
||||||
Generate a GPG key with OpenPGP without specifying a passphrase:
|
Generate a GPG/OpenPGP key with no passphrase (`%no-protection`):
|
||||||
|
|
||||||
```console
|
```sh
|
||||||
$ gpg --full-generate-key
|
export KEY_NAME="cluster0.yourdomain.com"
|
||||||
|
export KEY_COMMENT="flux secrets"
|
||||||
|
|
||||||
Real name: stefanprodan
|
gpg --batch --full-generate-key <<EOF
|
||||||
Email address: stefanprodan@users.noreply.github.com
|
%no-protection
|
||||||
Comment:
|
Key-Type: 1
|
||||||
You selected this USER-ID:
|
Key-Length: 4096
|
||||||
"stefanprodan <stefanprodan@users.noreply.github.com>"
|
Subkey-Type: 1
|
||||||
|
Subkey-Length: 4096
|
||||||
|
Expire-Date: 0
|
||||||
|
Name-Comment: ${KEY_COMMENT}
|
||||||
|
Name-Real: ${KEY_NAME}
|
||||||
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
Retrieve the GPG key ID (second row of the sec column):
|
The above configuration creates an rsa4096 key that does not expire.
|
||||||
|
For a full list of options to consider for your environment, see [Unattended GPG key generation](https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html).
|
||||||
|
|
||||||
```console
|
Retrieve the GPG key fingerprint (second row of the sec column):
|
||||||
$ gpg --list-secret-keys stefanprodan@users.noreply.github.com
|
|
||||||
|
|
||||||
sec rsa3072 2020-09-06 [SC]
|
```sh
|
||||||
|
gpg --list-secret-keys "${KEY_NAME}"
|
||||||
|
|
||||||
|
sec rsa4096 2020-09-06 [SC]
|
||||||
1F3D1CED2F865F5E59CA564553241F147E7C5FA4
|
1F3D1CED2F865F5E59CA564553241F147E7C5FA4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Store the key fingerprint as an environment variable:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export KEY_FP=1F3D1CED2F865F5E59CA564553241F147E7C5FA4
|
||||||
|
```
|
||||||
|
|
||||||
Export the public and private keypair from your local GPG keyring and
|
Export the public and private keypair from your local GPG keyring and
|
||||||
create a Kubernetes secret named `sops-gpg` in the `flux-system` namespace:
|
create a Kubernetes secret named `sops-gpg` in the `flux-system` namespace:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
gpg --export-secret-keys \
|
gpg --export-secret-keys --armor "${KEY_FP}" |
|
||||||
--armor 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 |
|
|
||||||
kubectl create secret generic sops-gpg \
|
kubectl create secret generic sops-gpg \
|
||||||
--namespace=flux-system \
|
--namespace=flux-system \
|
||||||
--from-file=sops.asc=/dev/stdin
|
--from-file=sops.asc=/dev/stdin
|
||||||
```
|
```
|
||||||
|
|
||||||
|
It's a good idea to back up this secret-key/K8s-Secret with a password manager or offline storage.
|
||||||
|
Also consider deleting the secret decryption key from you machine:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gpg --delete-secret-keys "${KEY_FP}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configure in-cluster secrets decryption
|
||||||
|
|
||||||
|
Register the Git repository on your cluster:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flux create source git my-secrets \
|
||||||
|
--url=https://github.com/my-org/my-secrets
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a kustomization for reconciling the secrets on the cluster:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flux create kustomization my-secrets \
|
||||||
|
--source=my-secrets \
|
||||||
|
--path=./clusters/cluster0 \
|
||||||
|
--prune=true \
|
||||||
|
--interval=10m \
|
||||||
|
--decryption-provider=sops \
|
||||||
|
--decryption-secret=sops-gpg
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `sops-gpg` can contain more than one key, SOPS will try to decrypt the
|
||||||
|
secrets by iterating over all the private keys until it finds one that works.
|
||||||
|
|
||||||
|
## Optional: Export the public key into the Git directory
|
||||||
|
|
||||||
|
Commit the public key to the repository so that team members who clone the repo can encrypt new files:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gpg --export --armor "${KEY_FP}" > ./clusters/cluster0/.sops.pub.asc
|
||||||
|
```
|
||||||
|
|
||||||
|
Check the file contents to ensure it's the public key before adding it to the repo and committing.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git add ./clusters/cluster0/.sops.pub.asc
|
||||||
|
git commit -am 'Share GPG public key for secrets generation'
|
||||||
|
```
|
||||||
|
|
||||||
|
Team members can then import this key when they pull the Git repository:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gpg --import ./clusters/cluster0/.sops.pub.asc
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! hint
|
||||||
|
The public key is sufficient for creating brand new files.
|
||||||
|
The secret key is required for decrypting and editing existing files because SOPS computes a MAC on all values.
|
||||||
|
When using solely the public key to add or remove a field, the whole file should be deleted and recreated.
|
||||||
|
|
||||||
|
## Configure the Git directory for encryption
|
||||||
|
|
||||||
|
Write a [SOPS config file](https://github.com/mozilla/sops#using-sops-yaml-conf-to-select-kms-pgp-for-new-files) to the specific cluster or namespace directory used
|
||||||
|
to store encrypted objects with this particular GPG key's fingerprint.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
cat <<EOF > ./clusters/cluster0/.sops.yaml
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: .*.yaml
|
||||||
|
encrypted_regex: ^(data|stringData)$
|
||||||
|
pgp: ${KEY_FP}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
This config applies recursively to all sub-directories.
|
||||||
|
Multiple directories can use separate SOPS configs.
|
||||||
|
Contributors using the `sops` CLI to create and encrypt files
|
||||||
|
won't have to worry about specifying the proper key for the target cluster or namespace.
|
||||||
|
|
||||||
|
`encrypted_regex` helps encrypt the the proper `data` and `stringData` fields for Secrets.
|
||||||
|
You may wish to add other fields if you are encrypting other types of Objects.
|
||||||
|
|
||||||
|
!!! hint
|
||||||
|
Note that you should encrypt only the `data` or `stringData` section. Encrypting the Kubernetes
|
||||||
|
secret metadata, kind or apiVersion is not supported by kustomize-controller.
|
||||||
|
|
||||||
|
Ignore all `.sops.yaml` files in a [`.sourceignore`](../components/source/gitrepositories#excluding-files) file at the root of your repo.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
touch .sourceignore
|
||||||
|
echo '**/.sops.yaml' >> .sourceignore
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now commit your SOPS config.
|
||||||
|
|
||||||
## Encrypt secrets
|
## Encrypt secrets
|
||||||
|
|
||||||
Generate a Kubernetes secret manifest with kubectl:
|
Generate a Kubernetes secret manifest with kubectl:
|
||||||
@@ -63,47 +169,17 @@ kubectl -n default create secret generic basic-auth \
|
|||||||
-o yaml > basic-auth.yaml
|
-o yaml > basic-auth.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Encrypt the secret with sops using your GPG key:
|
Encrypt the secret with SOPS using your GPG key:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sops --encrypt \
|
sops --encrypt --in-place basic-auth.yaml
|
||||||
--pgp=1F3D1CED2F865F5E59CA564553241F147E7C5FA4 \
|
|
||||||
--encrypted-regex '^(data|stringData)$' \
|
|
||||||
--in-place basic-auth.yaml
|
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! hint
|
|
||||||
Note that you should encrypt only the `data` section. Encrypting the Kubernetes
|
|
||||||
secret metadata, kind or apiVersion is not supported by kustomize-controller.
|
|
||||||
|
|
||||||
You can now commit the encrypted secret to your Git repository.
|
You can now commit the encrypted secret to your Git repository.
|
||||||
|
|
||||||
!!! hint
|
!!! hint
|
||||||
Note that you shouldn't apply the encrypted secrets onto the cluster with kubectl. SOPS encrypted secrets are designed to be consumed by kustomize-controller.
|
Note that you shouldn't apply the encrypted secrets onto the cluster with kubectl. SOPS encrypted secrets are designed to be consumed by kustomize-controller.
|
||||||
|
|
||||||
## Configure secrets decryption
|
|
||||||
|
|
||||||
Registry the Git repository on your cluster:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
flux create source git my-secrets \
|
|
||||||
--url=https://github.com/my-org/my-secrets
|
|
||||||
```
|
|
||||||
|
|
||||||
Create a kustomization for reconciling the secrets on the cluster:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
flux create kustomization my-secrets \
|
|
||||||
--source=my-secrets \
|
|
||||||
--prune=true \
|
|
||||||
--interval=10m \
|
|
||||||
--decryption-provider=sops \
|
|
||||||
--decryption-secret=sops-gpg
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the `sops-gpg` can contain more than one key, sops will try to decrypt the
|
|
||||||
secrets by iterating over all the private keys until it finds one that works.
|
|
||||||
|
|
||||||
### Using various cloud providers
|
### Using various cloud providers
|
||||||
|
|
||||||
When using AWS/GCP KMS, you don't have to include the gpg `secretRef` under
|
When using AWS/GCP KMS, you don't have to include the gpg `secretRef` under
|
||||||
@@ -210,5 +286,5 @@ Once the manifests have been pushed to the Git repository, the following happens
|
|||||||
|
|
||||||
* source-controller pulls the changes from Git
|
* source-controller pulls the changes from Git
|
||||||
* kustomize-controller loads the GPG keys from the `sops-pgp` secret
|
* kustomize-controller loads the GPG keys from the `sops-pgp` secret
|
||||||
* kustomize-controller decrypts the Kubernetes secrets with sops and applies them on the cluster
|
* kustomize-controller decrypts the Kubernetes secrets with SOPS and applies them on the cluster
|
||||||
* kubelet creates the pods and mounts the secret as a volume or env variable inside the app container
|
* kubelet creates the pods and mounts the secret as a volume or env variable inside the app container
|
||||||
|
|||||||
38
docs/migration/timetable.md
Normal file
38
docs/migration/timetable.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
hide:
|
||||||
|
# The table data on this page is easier to read when wider
|
||||||
|
# The TOC right column is already blank anyway
|
||||||
|
- toc
|
||||||
|
---
|
||||||
|
# Migration and Support Timetable
|
||||||
|
|
||||||
|
!!! heart "Flux Migration Commitment"
|
||||||
|
This public timetable clarifies our commitment to end users.
|
||||||
|
Its purpose is to help improve your experience in deciding how and when to plan infra decisions related to Flux versions.
|
||||||
|
Please refer to the [Roadmap](../roadmap/index.md) for additional details.
|
||||||
|
|
||||||
|
<!-- Note: this div allows us to set fixed column widths in custom.css -->
|
||||||
|
<!-- See: https://github.com/squidfunk/mkdocs-material/issues/118 -->
|
||||||
|
<div markdown="1" class="timetable-explicit-col-widths">
|
||||||
|
|
||||||
|
<!-- Requires mkdocs markdown_extensions footnotes and pymdownx.caret -->
|
||||||
|
<!-- markdownlint-disable-file MD033 -->
|
||||||
|
| Date | Flux 1 | Flux 2 CLI | GOTK[^1] |
|
||||||
|
| -- | -- | -- | -- |
|
||||||
|
| Oct 6, 2020 | ^^[Maintenance Mode](https://github.com/fluxcd/website/pull/25)^^<br><ul><li>Flux 1 releases only include critical bug fixes (which don’t require changing Flux 1 architecture), and security patches (for OS packages, Go runtime, and kubectl). No new features</li><li>Existing projects encouraged to test migration to Flux 2 pre-releases in non-production</li></ul> | ^^Development Mode^^<br><ul><li>Working to finish parity with Flux 1</li><li>New projects encouraged to test Flux 2 pre-releases in non-production</li></ul> | ^^All Alpha^^[^2] |
|
||||||
|
Feb 18, 2021 | ^^Partial Migration Mode^^<br><ul><li>Existing projects encouraged to migrate to `v1beta1`/`v2beta1` if you only use those features (Flux 1 read-only mode, and Helm Operator)</li><li>Existing projects encouraged to test image automation Alpha in non-production</li></ul> | ^^Feature Parity^^ | ^^Image Automation Alpha. All others reached Feature Parity, Beta^^ |
|
||||||
|
| TBD | ^^Superseded^^<br><ul><li>All existing projects encouraged to [migrate to Flux 2](https://toolkit.fluxcd.io/guides/flux-v1-migration/), and [report any bugs](https://github.com/fluxcd/flux2/issues/new/choose)</li><li>Flux 1 Helm Operator archived – no further updates due to unsupported dependencies</li></ul> | ^^Needs further testing, may get breaking changes^^<br><ul><li>CLI needs further user testing during this migration period</li></ul> | ^^All Beta, Production Ready^^[^3]<br><ul><li>All Flux 1 features stable and supported in Flux 2</li><li>Promoting Alpha versions to Beta makes this Production Ready</li></ul> |
|
||||||
|
| TBD | ^^Migration and security support only^^<br><ul><li>Flux 1 releases only include security patches (no bug fixes)</li><li>Maintainers support users with migration to Flux 2 only, no longer with Flux 1 issues</li><li>Flux 1 archive date announced</li></ul> | ^^Public release (GA), Production Ready^^<br><ul><li>CLI commits to backwards compatibility moving forward</li><li>CLI follows kubectl style backwards compatibility support: +1 -1 MINOR version for server components (e.g., APIs, Controllers, validation webhooks)</li></ul> | ^^All Beta, Production Ready^^ |
|
||||||
|
| TBD | ^^Archived^^<br><ul><li>Flux 1 obsolete, no further releases or maintainer support</li><li>Flux 1 repo archived</li></ul> | ^^Continued active development^^ | ^^Continued active development^^ |
|
||||||
|
|
||||||
|
<!-- end .timetable-explicit-col-widths -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
[^1]: GOTK is shorthand for the [GitOps Toolkit](https://toolkit.fluxcd.io/components/) APIs and Controllers
|
||||||
|
|
||||||
|
[^2]: Versioning: Flux 2 is a multi-service architecture, so requires a more complex explanation than Flux 1:
|
||||||
|
- Flux 2 CLI follows [Semantic Versioning](https://semver.org/) scheme
|
||||||
|
- The GitOps Toolkit APIs follow the [Kubernetes API versioning](https://kubernetes.io/docs/reference/using-api/#api-versioning) pattern. See [Roadmap](https://toolkit.fluxcd.io/roadmap/) for component versions.
|
||||||
|
- These are coordinated for cross-compatibility: For each Flux 2 CLI tag, CLI and GOTK versions are end-to-end tested together, so you may safely upgrade from one MINOR/PATCH version to another.
|
||||||
|
|
||||||
|
[^3]: The GOTK Custom Resource Definitions which are at `v1beta1` and `v2beta1` and their controllers are considered stable and production ready. Going forward, breaking changes to the beta CRDs will be accompanied by a conversion mechanism.
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
The Flux custom resource definitions which are at `v1beta1` and `v2beta1`
|
The Flux custom resource definitions which are at `v1beta1` and `v2beta1`
|
||||||
and their controllers are considered stable and production ready.
|
and their controllers are considered stable and production ready.
|
||||||
Going forward, breaking changes to the beta CRDs will be accompanied by a conversion mechanism.
|
Going forward, breaking changes to the beta CRDs will be accompanied by a conversion mechanism.
|
||||||
|
Please see the [Migration and Suport Timetable](../migration/timetable.md) for our commitment to end users.
|
||||||
|
|
||||||
The following components (included by default in [flux bootstrap](../guides/installation.md#bootstrap))
|
The following components (included by default in [flux bootstrap](../guides/installation.md#bootstrap))
|
||||||
are considered production ready:
|
are considered production ready:
|
||||||
|
|||||||
16
go.mod
16
go.mod
@@ -5,18 +5,18 @@ go 1.16
|
|||||||
require (
|
require (
|
||||||
github.com/Masterminds/semver/v3 v3.1.0
|
github.com/Masterminds/semver/v3 v3.1.0
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2
|
github.com/cyphar/filepath-securejoin v0.2.2
|
||||||
github.com/fluxcd/helm-controller/api v0.8.1
|
github.com/fluxcd/helm-controller/api v0.8.2
|
||||||
github.com/fluxcd/image-automation-controller/api v0.6.1
|
github.com/fluxcd/image-automation-controller/api v0.7.0
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.7.0
|
github.com/fluxcd/image-reflector-controller/api v0.7.1
|
||||||
github.com/fluxcd/kustomize-controller/api v0.9.1
|
github.com/fluxcd/kustomize-controller/api v0.9.3
|
||||||
github.com/fluxcd/notification-controller/api v0.9.0
|
github.com/fluxcd/notification-controller/api v0.10.0
|
||||||
github.com/fluxcd/pkg/apis/meta v0.8.0
|
github.com/fluxcd/pkg/apis/meta v0.8.0
|
||||||
github.com/fluxcd/pkg/git v0.3.0
|
github.com/fluxcd/pkg/git v0.3.0
|
||||||
github.com/fluxcd/pkg/runtime v0.8.3
|
github.com/fluxcd/pkg/runtime v0.8.5
|
||||||
github.com/fluxcd/pkg/ssh v0.0.5
|
github.com/fluxcd/pkg/ssh v0.0.5
|
||||||
github.com/fluxcd/pkg/untar v0.0.5
|
github.com/fluxcd/pkg/untar v0.0.5
|
||||||
github.com/fluxcd/pkg/version v0.0.1
|
github.com/fluxcd/pkg/version v0.0.1
|
||||||
github.com/fluxcd/source-controller/api v0.9.0
|
github.com/fluxcd/source-controller/api v0.9.1
|
||||||
github.com/google/go-containerregistry v0.2.0
|
github.com/google/go-containerregistry v0.2.0
|
||||||
github.com/manifoldco/promptui v0.7.0
|
github.com/manifoldco/promptui v0.7.0
|
||||||
github.com/olekukonko/tablewriter v0.0.4
|
github.com/olekukonko/tablewriter v0.0.4
|
||||||
@@ -29,7 +29,7 @@ require (
|
|||||||
k8s.io/cli-runtime v0.20.2 // indirect
|
k8s.io/cli-runtime v0.20.2 // indirect
|
||||||
k8s.io/client-go v0.20.2
|
k8s.io/client-go v0.20.2
|
||||||
sigs.k8s.io/cli-utils v0.22.2
|
sigs.k8s.io/cli-utils v0.22.2
|
||||||
sigs.k8s.io/controller-runtime v0.8.2
|
sigs.k8s.io/controller-runtime v0.8.3
|
||||||
sigs.k8s.io/kustomize/api v0.7.4
|
sigs.k8s.io/kustomize/api v0.7.4
|
||||||
sigs.k8s.io/yaml v1.2.0
|
sigs.k8s.io/yaml v1.2.0
|
||||||
)
|
)
|
||||||
|
|||||||
34
go.sum
34
go.sum
@@ -188,33 +188,33 @@ github.com/evanphx/json-patch/v5 v5.1.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
|
|||||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fluxcd/helm-controller/api v0.8.1 h1:AEmw/xaRi2y9lD6TB+2w1Govj7OhD5oxoDx6HGty1yM=
|
github.com/fluxcd/helm-controller/api v0.8.2 h1:ELSC6dal01jtzn8B6ffArNklbul9/k9lpEd6msefVAE=
|
||||||
github.com/fluxcd/helm-controller/api v0.8.1/go.mod h1:cFceNc/mOBa+Qi3NE8NDY2w3FAEectauTm8c10mcBis=
|
github.com/fluxcd/helm-controller/api v0.8.2/go.mod h1:WDVuo3g6n3eZy8l5U/Zqo0aL+LcFV1C/HoNAUzWLtzU=
|
||||||
github.com/fluxcd/image-automation-controller/api v0.6.1 h1:LgjjNYXrVojfgjit37GA0SDYre3AaDabYzT7L6lWO7I=
|
github.com/fluxcd/image-automation-controller/api v0.7.0 h1:mLaELYT52/FpZ93Mr+QMSK8UT0OBVQT4oA9kxO8NiEk=
|
||||||
github.com/fluxcd/image-automation-controller/api v0.6.1/go.mod h1:8Q/baOONPrSJFMq7+zxp/t2WGrqVFRUx4HnTrg37pNE=
|
github.com/fluxcd/image-automation-controller/api v0.7.0/go.mod h1:7E2dCvoxmTkDttp+Hk8v9eoSK/CdFmFhRKInEXC3yVY=
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.7.0 h1:Mlu9ybrL+MtWcaIex4+FOcYuk+0vA/7bYj8MxVvLR1A=
|
github.com/fluxcd/image-reflector-controller/api v0.7.1 h1:Cng36D1J25WYZ0ZB6dwzDtGR9MIyIcSUMYxHpb0IYXA=
|
||||||
github.com/fluxcd/image-reflector-controller/api v0.7.0/go.mod h1:KHWknF2xu/GZ4uLSQcAmfONZYjsbwNqyk3OvMQTmMsA=
|
github.com/fluxcd/image-reflector-controller/api v0.7.1/go.mod h1:J18L71jiHYrAu2dg0tgOkOjP+GtQldC1oslhTeX0jqc=
|
||||||
github.com/fluxcd/kustomize-controller/api v0.9.1 h1:o6cxtLiXUdEeTJMxoeoLdld7hsgf7L4mNO6+i2MD2U8=
|
github.com/fluxcd/kustomize-controller/api v0.9.3 h1:VbeU97pmx3vmgverqZIRyyBm1IKyPBZZAIo7mc3fZ+8=
|
||||||
github.com/fluxcd/kustomize-controller/api v0.9.1/go.mod h1:VhUwaSsgrXVgO8Qcx6ZO0isqb5TpDgbyyitCeXYqSM4=
|
github.com/fluxcd/kustomize-controller/api v0.9.3/go.mod h1:MDTwohIXqbId3qbhVNF7lAYLSBMzxq5MHINFN4bqDRs=
|
||||||
github.com/fluxcd/notification-controller/api v0.9.0 h1:aEIZu01EHlDH7I8/TyOkvMknlDV8NBNhuZ9cMQ8Kp0Q=
|
github.com/fluxcd/notification-controller/api v0.10.0 h1:7mxeBPnFzpL4Z+X5YiytQRzaDKrryb6TIQkC9ASJO28=
|
||||||
github.com/fluxcd/notification-controller/api v0.9.0/go.mod h1:nJqSGiecNkJLxuO2KWMu5YUTLaYT/A57854FMm4oX9Q=
|
github.com/fluxcd/notification-controller/api v0.10.0/go.mod h1:CA02ixmq+kFN9eBkruvJClkMqffgRjYBMxym3AfhO6c=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v0.0.1 h1:TkA80R0GopRY27VJqzKyS6ifiKIAfwBd7OHXtV3t2CI=
|
github.com/fluxcd/pkg/apis/kustomize v0.0.1 h1:TkA80R0GopRY27VJqzKyS6ifiKIAfwBd7OHXtV3t2CI=
|
||||||
github.com/fluxcd/pkg/apis/kustomize v0.0.1/go.mod h1:JAFPfnRmcrAoG1gNiA8kmEXsnOBuDyZ/F5X4DAQcVV0=
|
github.com/fluxcd/pkg/apis/kustomize v0.0.1/go.mod h1:JAFPfnRmcrAoG1gNiA8kmEXsnOBuDyZ/F5X4DAQcVV0=
|
||||||
github.com/fluxcd/pkg/apis/meta v0.7.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
|
||||||
github.com/fluxcd/pkg/apis/meta v0.8.0 h1:wqWpUsxhKHB1ZztcvOz+vnyhdKW9cWmjFp8Vci/XOdk=
|
github.com/fluxcd/pkg/apis/meta v0.8.0 h1:wqWpUsxhKHB1ZztcvOz+vnyhdKW9cWmjFp8Vci/XOdk=
|
||||||
github.com/fluxcd/pkg/apis/meta v0.8.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
github.com/fluxcd/pkg/apis/meta v0.8.0/go.mod h1:yHuY8kyGHYz22I0jQzqMMGCcHViuzC/WPdo9Gisk8Po=
|
||||||
github.com/fluxcd/pkg/git v0.3.0 h1:nrKZWZ/ymDevud3Wf1LEieO/QcNPnqz1/MrkZBFcg9o=
|
github.com/fluxcd/pkg/git v0.3.0 h1:nrKZWZ/ymDevud3Wf1LEieO/QcNPnqz1/MrkZBFcg9o=
|
||||||
github.com/fluxcd/pkg/git v0.3.0/go.mod h1:ZwG0iLOqNSyNw6lsPIAO+v6+BqqCXyV+r1Oq6Lm+slg=
|
github.com/fluxcd/pkg/git v0.3.0/go.mod h1:ZwG0iLOqNSyNw6lsPIAO+v6+BqqCXyV+r1Oq6Lm+slg=
|
||||||
github.com/fluxcd/pkg/runtime v0.8.3 h1:Zjk4fyAfBdBQ4GTokjisab7KyHHczCqKSpJi8+oVrNw=
|
github.com/fluxcd/pkg/runtime v0.8.4/go.mod h1:JD0eZIn5xkTeHHQUWXSqJPIh/ecO0d0qrUKbSVHnpnw=
|
||||||
github.com/fluxcd/pkg/runtime v0.8.3/go.mod h1:AM/hMD0mKtRqhKPU7NGDzm+3UXPpdnX8oBlcxLt11AY=
|
github.com/fluxcd/pkg/runtime v0.8.5 h1:ynh8fszbLQ3QSisQBNOABEUTnvt+/QfCdaL6gOJQcoQ=
|
||||||
|
github.com/fluxcd/pkg/runtime v0.8.5/go.mod h1:JD0eZIn5xkTeHHQUWXSqJPIh/ecO0d0qrUKbSVHnpnw=
|
||||||
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
|
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
|
||||||
github.com/fluxcd/pkg/ssh v0.0.5/go.mod h1:7jXPdXZpc0ttMNz2kD9QuMi3RNn/e0DOFbj0Tij/+Hs=
|
github.com/fluxcd/pkg/ssh v0.0.5/go.mod h1:7jXPdXZpc0ttMNz2kD9QuMi3RNn/e0DOFbj0Tij/+Hs=
|
||||||
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
|
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
|
||||||
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
|
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
|
||||||
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
|
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
|
||||||
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
|
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
|
||||||
github.com/fluxcd/source-controller/api v0.9.0 h1:ohV8AvmvkUK0N7+YKPIOlMSLaNG0SpFcNLtlmW18xuM=
|
github.com/fluxcd/source-controller/api v0.9.1 h1:kaL+tBflccsuj3NDESPPQyKXlZXlAgyNoT2nYY02JAE=
|
||||||
github.com/fluxcd/source-controller/api v0.9.0/go.mod h1:68+cPuz1G45f0SDRwEfTL419011ffveLIDA9nssLlkU=
|
github.com/fluxcd/source-controller/api v0.9.1/go.mod h1:Vuw+7UqEUUOdkKBfTUPHwaQgbn6LL2FwqPDx2UAk7NE=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
@@ -1205,8 +1205,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyz
|
|||||||
sigs.k8s.io/cli-utils v0.22.2 h1:xPD02b++uK990/dAg/rM0LKDOb2sTWZPI1v8IZPfCn0=
|
sigs.k8s.io/cli-utils v0.22.2 h1:xPD02b++uK990/dAg/rM0LKDOb2sTWZPI1v8IZPfCn0=
|
||||||
sigs.k8s.io/cli-utils v0.22.2/go.mod h1:unl8itcwGPqo41QSyksbXTWFbfMqap1o/4oiUxPnQfw=
|
sigs.k8s.io/cli-utils v0.22.2/go.mod h1:unl8itcwGPqo41QSyksbXTWFbfMqap1o/4oiUxPnQfw=
|
||||||
sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
|
sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
|
||||||
sigs.k8s.io/controller-runtime v0.8.2 h1:SBWmI0b3uzMIUD/BIXWNegrCeZmPJ503pOtwxY0LPHM=
|
sigs.k8s.io/controller-runtime v0.8.3 h1:GMHvzjTmaWHQB8HadW+dIvBoJuLvZObYJ5YoZruPRao=
|
||||||
sigs.k8s.io/controller-runtime v0.8.2/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
|
sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU=
|
||||||
sigs.k8s.io/kind v0.9.0/go.mod h1:cxKQWwmbtRDzQ+RNKnR6gZG6fjbeTtItp5cGf+ww+1Y=
|
sigs.k8s.io/kind v0.9.0/go.mod h1:cxKQWwmbtRDzQ+RNKnR6gZG6fjbeTtItp5cGf+ww+1Y=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.1/helm-controller.crds.yaml
|
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.2/helm-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.1/helm-controller.deployment.yaml
|
- https://github.com/fluxcd/helm-controller/releases/download/v0.8.2/helm-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.6.1/image-automation-controller.crds.yaml
|
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.7.0/image-automation-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.6.1/image-automation-controller.deployment.yaml
|
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.7.0/image-automation-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.0/image-reflector-controller.crds.yaml
|
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.1/image-reflector-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.0/image-reflector-controller.deployment.yaml
|
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.7.1/image-reflector-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.2/kustomize-controller.crds.yaml
|
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.3/kustomize-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.2/kustomize-controller.deployment.yaml
|
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.9.3/kustomize-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/notification-controller/releases/download/v0.9.0/notification-controller.crds.yaml
|
- https://github.com/fluxcd/notification-controller/releases/download/v0.10.0/notification-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/notification-controller/releases/download/v0.9.0/notification-controller.deployment.yaml
|
- https://github.com/fluxcd/notification-controller/releases/download/v0.10.0/notification-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v0.9.0/source-controller.crds.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v0.9.1/source-controller.crds.yaml
|
||||||
- https://github.com/fluxcd/source-controller/releases/download/v0.9.0/source-controller.deployment.yaml
|
- https://github.com/fluxcd/source-controller/releases/download/v0.9.1/source-controller.deployment.yaml
|
||||||
- account.yaml
|
- account.yaml
|
||||||
patchesJson6902:
|
patchesJson6902:
|
||||||
- target:
|
- target:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright 2020 The Flux authors. All rights reserved.
|
# Copyright 2020, 2021 The Flux authors. All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
IN_PATH=${1:-"$(git rev-parse --show-toplevel)/manifests"}
|
||||||
OUT_PATH=${1:-"${REPO_ROOT}/cmd/flux/manifests"}
|
OUT_PATH=${2:-"$(git rev-parse --show-toplevel)/cmd/flux/manifests"}
|
||||||
TAR=${2}
|
TAR=${3}
|
||||||
|
|
||||||
info() {
|
info() {
|
||||||
echo '[INFO] ' "$@"
|
echo '[INFO] ' "$@"
|
||||||
@@ -45,20 +45,20 @@ files=""
|
|||||||
info using "$(kustomize version --short)"
|
info using "$(kustomize version --short)"
|
||||||
|
|
||||||
# build controllers
|
# build controllers
|
||||||
for controller in ${REPO_ROOT}/manifests/bases/*/; do
|
for controller in ${IN_PATH}/bases/*/; do
|
||||||
output_path="${OUT_PATH}/$(basename $controller).yaml"
|
output_path="${OUT_PATH}/$(basename $controller).yaml"
|
||||||
build $controller $output_path
|
build $controller $output_path
|
||||||
files+=" $(basename $output_path)"
|
files+=" $(basename $output_path)"
|
||||||
done
|
done
|
||||||
|
|
||||||
# build rbac
|
# build rbac
|
||||||
rbac_path="${REPO_ROOT}/manifests/rbac"
|
rbac_path="${IN_PATH}/rbac"
|
||||||
rbac_output_path="${OUT_PATH}/rbac.yaml"
|
rbac_output_path="${OUT_PATH}/rbac.yaml"
|
||||||
build $rbac_path $rbac_output_path
|
build $rbac_path $rbac_output_path
|
||||||
files+=" $(basename $rbac_output_path)"
|
files+=" $(basename $rbac_output_path)"
|
||||||
|
|
||||||
# build policies
|
# build policies
|
||||||
policies_path="${REPO_ROOT}/manifests/policies"
|
policies_path="${IN_PATH}/policies"
|
||||||
policies_output_path="${OUT_PATH}/policies.yaml"
|
policies_output_path="${OUT_PATH}/policies.yaml"
|
||||||
build $policies_path $policies_output_path
|
build $policies_path $policies_output_path
|
||||||
files+=" $(basename $policies_output_path)"
|
files+=" $(basename $policies_output_path)"
|
||||||
|
|||||||
32
mkdocs.yml
32
mkdocs.yml
@@ -26,31 +26,34 @@ plugins:
|
|||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- admonition
|
- admonition
|
||||||
- meta
|
|
||||||
- codehilite:
|
- codehilite:
|
||||||
guess_lang: false
|
guess_lang: false
|
||||||
- toc:
|
- footnotes
|
||||||
permalink: true
|
- meta
|
||||||
|
- pymdownx.caret
|
||||||
|
- pymdownx.emoji:
|
||||||
|
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||||
|
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||||
|
- pymdownx.extra
|
||||||
|
- pymdownx.progressbar
|
||||||
- pymdownx.superfences:
|
- pymdownx.superfences:
|
||||||
highlight_code: true
|
highlight_code: true
|
||||||
- pymdownx.tabbed
|
- pymdownx.tabbed
|
||||||
- pymdownx.tilde
|
|
||||||
- pymdownx.progressbar
|
|
||||||
- pymdownx.tasklist
|
- pymdownx.tasklist
|
||||||
- pymdownx.superfences
|
- pymdownx.tilde
|
||||||
- pymdownx.emoji:
|
- toc:
|
||||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
permalink: true
|
||||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
- Introduction: index.md
|
- Introduction: index.md
|
||||||
- Core Concepts: core-concepts/index.md
|
- Core Concepts: core-concepts/index.md
|
||||||
- Get Started: get-started/index.md
|
- Get Started: get-started/index.md
|
||||||
- Migration:
|
- Migration:
|
||||||
- Migrate from Flux v1: guides/flux-v1-migration.md
|
- Migration and Support Timetable: migration/timetable.md
|
||||||
- Migrate from Flux v1 image update automation: guides/flux-v1-automation-migration.md
|
- Migrate from Flux v1: guides/flux-v1-migration.md
|
||||||
- Migrate from the Helm Operator: guides/helm-operator-migration.md
|
- Migrate from Flux v1 image update automation: guides/flux-v1-automation-migration.md
|
||||||
- FAQ: guides/faq-migration.md
|
- Migrate from the Helm Operator: guides/helm-operator-migration.md
|
||||||
|
- FAQ: guides/faq-migration.md
|
||||||
- Guides:
|
- Guides:
|
||||||
- Installation: guides/installation.md
|
- Installation: guides/installation.md
|
||||||
- Manage Helm Releases: guides/helmreleases.md
|
- Manage Helm Releases: guides/helmreleases.md
|
||||||
@@ -145,6 +148,7 @@ nav:
|
|||||||
- Get kustomizations: cmd/flux_get_kustomizations.md
|
- Get kustomizations: cmd/flux_get_kustomizations.md
|
||||||
- Get helmreleases: cmd/flux_get_helmreleases.md
|
- Get helmreleases: cmd/flux_get_helmreleases.md
|
||||||
- Get sources: cmd/flux_get_sources.md
|
- Get sources: cmd/flux_get_sources.md
|
||||||
|
- Get sources all: cmd/flux_get_sources_all.md
|
||||||
- Get sources git: cmd/flux_get_sources_git.md
|
- Get sources git: cmd/flux_get_sources_git.md
|
||||||
- Get sources helm: cmd/flux_get_sources_helm.md
|
- Get sources helm: cmd/flux_get_sources_helm.md
|
||||||
- Get sources chart: cmd/flux_get_sources_chart.md
|
- Get sources chart: cmd/flux_get_sources_chart.md
|
||||||
@@ -154,10 +158,12 @@ nav:
|
|||||||
- Get alert providers: cmd/flux_get_alert-providers.md
|
- Get alert providers: cmd/flux_get_alert-providers.md
|
||||||
- Get receivers: cmd/flux_get_receivers.md
|
- Get receivers: cmd/flux_get_receivers.md
|
||||||
- Get images: cmd/flux_get_images.md
|
- Get images: cmd/flux_get_images.md
|
||||||
|
- Get images all: cmd/flux_get_images_all.md
|
||||||
- Get images policy: cmd/flux_get_images_policy.md
|
- Get images policy: cmd/flux_get_images_policy.md
|
||||||
- Get images repository: cmd/flux_get_images_repository.md
|
- Get images repository: cmd/flux_get_images_repository.md
|
||||||
- Get images update: cmd/flux_get_images_update.md
|
- Get images update: cmd/flux_get_images_update.md
|
||||||
- Install: cmd/flux_install.md
|
- Install: cmd/flux_install.md
|
||||||
|
- Logs: cmd/flux_logs.md
|
||||||
- Resume: cmd/flux_resume.md
|
- Resume: cmd/flux_resume.md
|
||||||
- Resume kustomization: cmd/flux_resume_kustomization.md
|
- Resume kustomization: cmd/flux_resume_kustomization.md
|
||||||
- Resume helmrelease: cmd/flux_resume_helmrelease.md
|
- Resume helmrelease: cmd/flux_resume_helmrelease.md
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ type Logger interface {
|
|||||||
Generatef(format string, a ...interface{})
|
Generatef(format string, a ...interface{})
|
||||||
// Waitingf logs a formatted waiting message.
|
// Waitingf logs a formatted waiting message.
|
||||||
Waitingf(format string, a ...interface{})
|
Waitingf(format string, a ...interface{})
|
||||||
// Waitingf logs a formatted success message.
|
// Successf logs a formatted success message.
|
||||||
Successf(format string, a ...interface{})
|
Successf(format string, a ...interface{})
|
||||||
// Failuref logs a formatted failure message.
|
// Failuref logs a formatted failure message.
|
||||||
Failuref(format string, a ...interface{})
|
Failuref(format string, a ...interface{})
|
||||||
|
|||||||
109
pkg/status/status.go
Normal file
109
pkg/status/status.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020, 2021 The Flux authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package status
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/aggregator"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/collector"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/polling/event"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
|
||||||
|
"sigs.k8s.io/cli-utils/pkg/object"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||||
|
|
||||||
|
"github.com/fluxcd/flux2/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusChecker struct {
|
||||||
|
pollInterval time.Duration
|
||||||
|
timeout time.Duration
|
||||||
|
client client.Client
|
||||||
|
statusPoller *polling.StatusPoller
|
||||||
|
logger log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStatusChecker(kubeConfig *rest.Config, pollInterval time.Duration, timeout time.Duration, log log.Logger) (*StatusChecker, error) {
|
||||||
|
restMapper, err := apiutil.NewDynamicRESTMapper(kubeConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c, err := client.New(kubeConfig, client.Options{Mapper: restMapper})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &StatusChecker{
|
||||||
|
pollInterval: pollInterval,
|
||||||
|
timeout: timeout,
|
||||||
|
client: c,
|
||||||
|
statusPoller: polling.NewStatusPoller(c, restMapper),
|
||||||
|
logger: log,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *StatusChecker) Assess(identifiers ...object.ObjMetadata) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), sc.timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
opts := polling.Options{PollInterval: sc.pollInterval, UseCache: true}
|
||||||
|
eventsChan := sc.statusPoller.Poll(ctx, identifiers, opts)
|
||||||
|
|
||||||
|
coll := collector.NewResourceStatusCollector(identifiers)
|
||||||
|
done := coll.ListenWithObserver(eventsChan, desiredStatusNotifierFunc(cancel, status.CurrentStatus))
|
||||||
|
|
||||||
|
<-done
|
||||||
|
|
||||||
|
for _, rs := range coll.ResourceStatuses {
|
||||||
|
switch rs.Status {
|
||||||
|
case status.CurrentStatus:
|
||||||
|
sc.logger.Successf("%s: %s ready", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))
|
||||||
|
case status.NotFoundStatus:
|
||||||
|
sc.logger.Failuref("%s: %s not found", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))
|
||||||
|
default:
|
||||||
|
sc.logger.Failuref("%s: %s not ready", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if coll.Error != nil || ctx.Err() == context.DeadlineExceeded {
|
||||||
|
return fmt.Errorf("timed out waiting for condition")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// desiredStatusNotifierFunc returns an Observer function for the
|
||||||
|
// ResourceStatusCollector that will cancel the context (using the cancelFunc)
|
||||||
|
// when all resources have reached the desired status.
|
||||||
|
func desiredStatusNotifierFunc(cancelFunc context.CancelFunc,
|
||||||
|
desired status.Status) collector.ObserverFunc {
|
||||||
|
return func(rsc *collector.ResourceStatusCollector, _ event.Event) {
|
||||||
|
var rss []*event.ResourceStatus
|
||||||
|
for _, rs := range rsc.ResourceStatuses {
|
||||||
|
rss = append(rss, rs)
|
||||||
|
}
|
||||||
|
aggStatus := aggregator.AggregateStatus(rss, desired)
|
||||||
|
if aggStatus == desired {
|
||||||
|
cancelFunc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user