Compare commits
131 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
473e226883 | ||
|
|
2ebb06d330 | ||
|
|
cc88e68c4e | ||
|
|
f8704747d9 | ||
|
|
0c33df883c | ||
|
|
3fbc396bc8 | ||
|
|
17df7a46e2 | ||
|
|
925c1d3d8e | ||
|
|
1976d4cc1b | ||
|
|
d98578f260 | ||
|
|
8d1dddf205 | ||
|
|
2584b6ca5b | ||
|
|
70897cebfe | ||
|
|
0e80cd5c44 | ||
|
|
b979e313b2 | ||
|
|
533cb42d29 | ||
|
|
35a209903e | ||
|
|
824de61579 | ||
|
|
17ca3f8ac2 | ||
|
|
87a299736e | ||
|
|
e86286722a | ||
|
|
c4a0724c8d | ||
|
|
17139f34dd | ||
|
|
1779714b0d | ||
|
|
1ff4495737 | ||
|
|
02c0dc1217 | ||
|
|
fb43c194b9 | ||
|
|
ae94bb56d9 | ||
|
|
123433c4ea | ||
|
|
58619076ea | ||
|
|
a50d1c5784 | ||
|
|
91c8cb197f | ||
|
|
427c60618f | ||
|
|
2d417f200d | ||
|
|
54b11e7b25 | ||
|
|
50d2eb7d57 | ||
|
|
dfb20dd1ca | ||
|
|
4f22016f13 | ||
|
|
430a2d0454 | ||
|
|
db23c8ce9f | ||
|
|
ffd4784916 | ||
|
|
750830c302 | ||
|
|
d245ef9b39 | ||
|
|
c8586d1ef4 | ||
|
|
316cba1cb8 | ||
|
|
13dba62b8d | ||
|
|
c2ff169c08 | ||
|
|
57a1dbfc6d | ||
|
|
efb39d6fc6 | ||
|
|
b784234430 | ||
|
|
aebad92426 | ||
|
|
8e67cfd5c9 | ||
|
|
10cc6d7e08 | ||
|
|
83c236c829 | ||
|
|
b6ab37691f | ||
|
|
c85af78025 | ||
|
|
2c2fc6dd97 | ||
|
|
3620b76139 | ||
|
|
ca5732e586 | ||
|
|
2463d72f3b | ||
|
|
d6f7474200 | ||
|
|
0b2bc7ab3f | ||
|
|
0a4fac61d4 | ||
|
|
797aec5528 | ||
|
|
5f0b95dc59 | ||
|
|
b384c5f14c | ||
|
|
5254dca9d9 | ||
|
|
8534ccbf37 | ||
|
|
9af874d810 | ||
|
|
4e3dee15ce | ||
|
|
aaad618e20 | ||
|
|
10bb50bd82 | ||
|
|
6d2ff6e019 | ||
|
|
670070a879 | ||
|
|
dcec8007d4 | ||
|
|
3abf4a49cd | ||
|
|
38825bf96a | ||
|
|
faa69da28d | ||
|
|
5cf524e2fd | ||
|
|
88802a44e7 | ||
|
|
94498d862d | ||
|
|
9418b24e8f | ||
|
|
b92cbcd7e7 | ||
|
|
9ef2ff92df | ||
|
|
422724bd2d | ||
|
|
6cb7897f25 | ||
|
|
499ba15004 | ||
|
|
b04abe989e | ||
|
|
ea576179f9 | ||
|
|
116d53a978 | ||
|
|
32adbf2ec8 | ||
|
|
c664484fda | ||
|
|
06906eba4c | ||
|
|
d387ebf32d | ||
|
|
f75556f33c | ||
|
|
2cf09e4de6 | ||
|
|
a5a3a9c586 | ||
|
|
746dfbd955 | ||
|
|
b1993d2fb7 | ||
|
|
e8096dec88 | ||
|
|
39eee51ec8 | ||
|
|
7bb3a10795 | ||
|
|
a8cbe4b05f | ||
|
|
fe86da0cde | ||
|
|
4c86a2c191 | ||
|
|
8dc5db17ac | ||
|
|
549c3a190e | ||
|
|
7a68c4ccf3 | ||
|
|
4c684df653 | ||
|
|
bf8831b833 | ||
|
|
394227571f | ||
|
|
bf67577073 | ||
|
|
e180611024 | ||
|
|
43cfc55368 | ||
|
|
c03b7ea15d | ||
|
|
ddfedfb590 | ||
|
|
24418370f1 | ||
|
|
02521b6964 | ||
|
|
16f693148b | ||
|
|
0bf46cb63f | ||
|
|
2e38855396 | ||
|
|
97592a1387 | ||
|
|
c61bf76c80 | ||
|
|
e95b137011 | ||
|
|
ad655183e0 | ||
|
|
789fd34c4a | ||
|
|
87bbbaa475 | ||
|
|
a4ca813cf5 | ||
|
|
e8eef73212 | ||
|
|
512d4a43cb | ||
|
|
b9f7b1d175 |
36
.github/workflows/docs.yaml
vendored
36
.github/workflows/docs.yaml
vendored
@@ -13,17 +13,35 @@ jobs:
|
||||
- name: Checkout master
|
||||
uses: actions/checkout@v1
|
||||
- name: Copy assets
|
||||
env:
|
||||
SOURCE_VER: ${{ 'v0.0.10' }}
|
||||
KUSTOMIZE_VER: ${{ 'v0.0.8' }}
|
||||
HELM_VER: ${{ 'v0.0.3' }}
|
||||
NOTIFICATION_VER: ${{ 'v0.0.7' }}
|
||||
run: |
|
||||
# source-controller CRDs
|
||||
curl "https://raw.githubusercontent.com/fluxcd/source-controller/$SOURCE_VER/docs/api/source.md" > docs/components/source/api.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/source-controller/$SOURCE_VER/docs/spec/v1alpha1/gitrepositories.md" > docs/components/source/gitrepositories.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/source-controller/$SOURCE_VER/docs/spec/v1alpha1/helmrepositories.md" > docs/components/source/helmrepositories.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/source-controller/$SOURCE_VER/docs/spec/v1alpha1/helmcharts.md" > docs/components/source/helmcharts.md
|
||||
|
||||
# kustomize-controller CRDs
|
||||
curl "https://raw.githubusercontent.com/fluxcd/kustomize-controller/$KUSTOMIZE_VER/docs/api/kustomize.md" > docs/components/kustomize/api.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/kustomize-controller/$KUSTOMIZE_VER/docs/spec/v1alpha1/kustomization.md" > docs/components/kustomize/kustomization.md
|
||||
|
||||
# helm-controller CRDs
|
||||
curl "https://raw.githubusercontent.com/fluxcd/helm-controller/$HELM_VER/docs/api/helmrelease.md" > docs/components/helm/api.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/helm-controller/$HELM_VER/docs/spec/v2alpha1/helmreleases.md" > docs/components/helm/helmreleases.md
|
||||
|
||||
# notification-controller CRDs
|
||||
curl "https://raw.githubusercontent.com/fluxcd/notification-controller/$NOTIFICATION_VER/docs/api/notification.md" > docs/components/notification/api.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/notification-controller/$NOTIFICATION_VER/docs/spec/v1alpha1/event.md" > docs/components/notification/event.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/notification-controller/$NOTIFICATION_VER/docs/spec/v1alpha1/alert.md" > docs/components/notification/alert.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/notification-controller/$NOTIFICATION_VER/docs/spec/v1alpha1/provider.md" > docs/components/notification/provider.md
|
||||
curl "https://raw.githubusercontent.com/fluxcd/notification-controller/$NOTIFICATION_VER/docs/spec/v1alpha1/receiver.md" > docs/components/notification/receiver.md
|
||||
|
||||
# install script
|
||||
cp install/tk.sh docs/install.sh
|
||||
curl https://raw.githubusercontent.com/fluxcd/source-controller/master/docs/api/source.md > docs/components/source/api.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/source-controller/master/docs/spec/v1alpha1/gitrepositories.md > docs/components/source/gitrepositories.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/source-controller/master/docs/spec/v1alpha1/helmrepositories.md > docs/components/source/helmrepositories.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/kustomize-controller/master/docs/api/kustomize.md > docs/components/kustomize/api.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/kustomize-controller/master/docs/spec/v1alpha1/kustomization.md > docs/components/kustomize/kustomization.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/api/notification.md > docs/components/notification/api.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/spec/v1alpha1/event.md > docs/components/notification/event.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/spec/v1alpha1/alert.md > docs/components/notification/alert.md
|
||||
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/spec/v1alpha1/provider.md > docs/components/notification/provider.md
|
||||
- name: Deploy docs
|
||||
uses: mhausenblas/mkdocs-deploy-gh-pages@master
|
||||
env:
|
||||
|
||||
31
.github/workflows/e2e.yaml
vendored
31
.github/workflows/e2e.yaml
vendored
@@ -24,7 +24,9 @@ jobs:
|
||||
with:
|
||||
go-version: 1.14.x
|
||||
- name: Setup Kubernetes
|
||||
uses: engineerd/setup-kind@v0.3.0
|
||||
uses: engineerd/setup-kind@v0.4.0
|
||||
with:
|
||||
image: kindest/node:v1.16.9
|
||||
- name: Run test
|
||||
run: make test
|
||||
- name: Check if working tree is dirty
|
||||
@@ -63,13 +65,13 @@ jobs:
|
||||
--path="./deploy/overlays/dev" \
|
||||
--prune=true \
|
||||
--interval=5m \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--health-check="Deployment/frontend.dev" \
|
||||
--health-check="Deployment/backend.dev" \
|
||||
--health-check-timeout=3m
|
||||
- name: tk sync kustomization --with-source
|
||||
run: |
|
||||
./bin/tk sync kustomization podinfo --with-source
|
||||
./bin/tk reconcile kustomization podinfo --with-source
|
||||
- name: tk get kustomizations
|
||||
run: |
|
||||
./bin/tk get kustomizations
|
||||
@@ -89,6 +91,29 @@ jobs:
|
||||
- name: tk delete source git
|
||||
run: |
|
||||
./bin/tk delete source git podinfo --silent
|
||||
- name: tk create source helm
|
||||
run: |
|
||||
./bin/tk create source helm podinfo \
|
||||
--url https://stefanprodan.github.io/podinfo
|
||||
- name: tk create helmrelease
|
||||
run: |
|
||||
./bin/tk create hr podinfo \
|
||||
--target-namespace=default \
|
||||
--source=podinfo \
|
||||
--chart-name=podinfo \
|
||||
--chart-version=">4.0.0 <5.0.0"
|
||||
- name: tk get helmreleases
|
||||
run: |
|
||||
./bin/tk get helmreleases
|
||||
- name: tk export helmrelease
|
||||
run: |
|
||||
./bin/tk export hr --all
|
||||
- name: tk delete helmrelease
|
||||
run: |
|
||||
./bin/tk delete hr podinfo --silent
|
||||
- name: tk delete source helm
|
||||
run: |
|
||||
./bin/tk delete source helm podinfo --silent
|
||||
- name: tk check
|
||||
run: |
|
||||
./bin/tk check
|
||||
|
||||
54
.github/workflows/release.yaml
vendored
54
.github/workflows/release.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
- name: Unshallow
|
||||
run: git fetch --prune --unshallow
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2-beta
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.14.x
|
||||
- name: Download release notes utility
|
||||
@@ -25,10 +25,60 @@ jobs:
|
||||
run: |
|
||||
echo 'CHANGELOG' > /tmp/release.txt
|
||||
github-release-notes -org fluxcd -repo toolkit -since-latest-release >> /tmp/release.txt
|
||||
- name: Setup Kustomize
|
||||
uses: ./.github/actions/kustomize
|
||||
- name: Generate manifests tarball
|
||||
run: |
|
||||
mkdir -p ./output
|
||||
files=""
|
||||
|
||||
# build controllers
|
||||
for controller in ./manifests/bases/*/; do
|
||||
output_path="./output/$(basename $controller).yaml"
|
||||
echo "building $controller to $output_path"
|
||||
|
||||
kustomize build $controller > $output_path
|
||||
files+=" $(basename $output_path)"
|
||||
done
|
||||
|
||||
# build rbac
|
||||
rbac_path="./manifests/rbac"
|
||||
rbac_output_path="./output/rbac.yaml"
|
||||
echo "building $rbac_path to $rbac_output_path"
|
||||
kustomize build $rbac_path > $rbac_output_path
|
||||
files+=" $(basename $rbac_output_path)"
|
||||
|
||||
# build policies
|
||||
policies_path="./manifests/policies"
|
||||
policies_output_path="./output/policies.yaml"
|
||||
echo "building $policies_path to $policies_output_path"
|
||||
kustomize build $policies_path > $policies_output_path
|
||||
files+=" $(basename $policies_output_path)"
|
||||
|
||||
# create tarball
|
||||
cd ./output && tar -cvzf manifests.tar.gz $files
|
||||
- name: Create release
|
||||
id: create_release
|
||||
uses: actions/create-release@latest
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ github.ref }}
|
||||
- name: Upload artifacts
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./output/manifests.tar.gz
|
||||
asset_name: manifests.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v1
|
||||
with:
|
||||
version: latest
|
||||
args: release --release-notes=/tmp/release.txt
|
||||
args: release --release-notes=/tmp/release.txt --skip-validate
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,4 +13,5 @@
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
bin/
|
||||
bin/
|
||||
output/
|
||||
@@ -1,8 +1,8 @@
|
||||
# Contributing
|
||||
|
||||
FluxCD toolkit is [Apache 2.0 licensed](LICENSE) and accepts contributions
|
||||
via GitHub pull requests. This document outlines some of the conventions on
|
||||
to make it easier to get your contribution accepted.
|
||||
The GitOps Toolkit is [Apache 2.0 licensed](https://github.com/fluxcd/toolkit/blob/master/LICENSE)
|
||||
and accepts contributions via GitHub pull requests. This document outlines
|
||||
some of the conventions on to make it easier to get your contribution accepted.
|
||||
|
||||
We gratefully welcome improvements to issues and documentation as well as to
|
||||
code.
|
||||
@@ -14,20 +14,43 @@ Origin (DCO). This document was created by the Linux Kernel community and is a
|
||||
simple statement that you, as a contributor, have the legal right to make the
|
||||
contribution. No action from you is required, but it's a good idea to see the
|
||||
[DCO](DCO) file for details before you start contributing code to FluxCD
|
||||
toolkit.
|
||||
organization.
|
||||
|
||||
## Communications
|
||||
|
||||
The project uses Slack: To join the conversation, simply join the
|
||||
[CNCF](https://slack.cncf.io/) Slack workspace and use the
|
||||
[#flux](https://cloud-native.slack.com/messages/flux/) channel.
|
||||
For realtime communications we use Slack: To join the conversation, simply
|
||||
join the [CNCF](https://slack.cncf.io/) Slack workspace and use the
|
||||
[#flux-dev](https://cloud-native.slack.com/messages/flux-dev/) channel.
|
||||
|
||||
The developers use a mailing list to discuss development as well.
|
||||
Simply subscribe to [flux-dev on cncf.io](https://lists.cncf.io/g/cncf-flux-dev)
|
||||
to join the conversation (this will also add an invitation to your
|
||||
Google calendar for our [Flux
|
||||
To discuss ideas and specifications we use [Github
|
||||
Discussions](https://github.com/fluxcd/toolkit/discussions).
|
||||
|
||||
For announcements we use a mailing list as well. Simply subscribe to
|
||||
[flux-dev on cncf.io](https://lists.cncf.io/g/cncf-flux-dev)
|
||||
to join the conversation (there you can also add calendar invites
|
||||
to your Google calendar for our [Flux
|
||||
meeting](https://docs.google.com/document/d/1l_M0om0qUEN_NNiGgpqJ2tvsF2iioHkaARDeh6b70B0/edit#)).
|
||||
|
||||
## Understanding the GitOps Toolkit
|
||||
|
||||
If you are entirely new to the GitOps Toolkit,
|
||||
you might want to take a look at the [introductory talk and demo](https://www.youtube.com/watch?v=qQBtSkgl7tI).
|
||||
|
||||
This project is composed of:
|
||||
|
||||
- [/f/toolkit](https://github.com/fluxcd/toolkit): The GitOps Toolkit CLI
|
||||
- [/f/source-manager](https://github.com/fluxcd/source-controller): Kubernetes operator for managing sources
|
||||
- [/f/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
|
||||
- [/f/notification-controller](https://github.com/fluxcd/notification-controller): Kubernetes operator for handling inbound and outbound events
|
||||
|
||||
### Understanding the code
|
||||
|
||||
To get started with developing controllers, you might want to review
|
||||
[our guide](https://toolkit.fluxcd.io/dev-guides/source-watcher/) which
|
||||
walks you through writing a short and concise controller that watches out
|
||||
for source changes.
|
||||
|
||||
### How to run the test suite
|
||||
|
||||
You can run the unit tests by simply doing
|
||||
@@ -57,7 +80,7 @@ get asked to resubmit the PR or divide the changes into more than one PR.
|
||||
|
||||
### Format of the Commit Message
|
||||
|
||||
For Source Controller we prefer the following rules for good commit messages:
|
||||
For the GitOps Toolkit controllers we prefer the following rules for good commit messages:
|
||||
|
||||
- Limit the subject to 50 characters and write as the continuation
|
||||
of the sentence "If applied, this commit will ..."
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# toolkit
|
||||
# GitOps Toolkit
|
||||
|
||||
[](https://github.com/fluxcd/toolkit/actions)
|
||||
[](https://goreportcard.com/report/github.com/fluxcd/toolkit)
|
||||
|
||||
@@ -45,7 +45,10 @@ var bootstrapCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
var (
|
||||
bootstrapVersion string
|
||||
bootstrapVersion string
|
||||
bootstrapComponents []string
|
||||
bootstrapRegistry string
|
||||
bootstrapImagePullSecret string
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -56,8 +59,14 @@ const (
|
||||
)
|
||||
|
||||
func init() {
|
||||
bootstrapCmd.PersistentFlags().StringVar(&bootstrapVersion, "version", "master", "toolkit tag or branch")
|
||||
|
||||
bootstrapCmd.PersistentFlags().StringVarP(&bootstrapVersion, "version", "v", defaultVersion,
|
||||
"toolkit version")
|
||||
bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapComponents, "components", defaultComponents,
|
||||
"list of components, accepts comma-separated values")
|
||||
bootstrapCmd.PersistentFlags().StringVar(&bootstrapRegistry, "registry", "docker.io/fluxcd",
|
||||
"container registry where the toolkit images are published")
|
||||
bootstrapCmd.PersistentFlags().StringVar(&bootstrapImagePullSecret, "image-pull-secret", "",
|
||||
"Kubernetes secret name used for pulling the toolkit images from a private registry")
|
||||
rootCmd.AddCommand(bootstrapCmd)
|
||||
}
|
||||
|
||||
@@ -69,7 +78,7 @@ func generateInstallManifests(targetPath, namespace, tmpDir string) (string, err
|
||||
return "", fmt.Errorf("generating manifests failed: %w", err)
|
||||
}
|
||||
|
||||
if err := genInstallManifests(bootstrapVersion, namespace, components, tkDir); err != nil {
|
||||
if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, bootstrapRegistry, bootstrapImagePullSecret, tkDir); err != nil {
|
||||
return "", fmt.Errorf("generating manifests failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -137,7 +146,6 @@ func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, inte
|
||||
}
|
||||
|
||||
gvk = kustomizev1.GroupVersion.WithKind("Kustomization")
|
||||
emptyAPIGroup := ""
|
||||
kustomization := kustomizev1.Kustomization{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: gvk.Kind,
|
||||
@@ -153,10 +161,9 @@ func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, inte
|
||||
},
|
||||
Path: fmt.Sprintf("./%s", strings.TrimPrefix(targetPath, "./")),
|
||||
Prune: true,
|
||||
SourceRef: corev1.TypedLocalObjectReference{
|
||||
APIGroup: &emptyAPIGroup,
|
||||
Kind: "GitRepository",
|
||||
Name: name,
|
||||
SourceRef: kustomizev1.CrossNamespaceObjectReference{
|
||||
Kind: sourcev1.GitRepositoryKind,
|
||||
Name: name,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -42,19 +42,19 @@ the bootstrap command will perform an upgrade if needed.`,
|
||||
export GITHUB_TOKEN=<my-token>
|
||||
|
||||
# Run bootstrap for a private repo owned by a GitHub organization
|
||||
bootstrap github --owner=<organization> --repository=<repo name>
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name>
|
||||
|
||||
# Run bootstrap for a private repo and assign organization teams to it
|
||||
bootstrap github --owner=<organization> --repository=<repo name> --team=<team1 slug> --team=<team2 slug>
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name> --team=<team1 slug> --team=<team2 slug>
|
||||
|
||||
# Run bootstrap for a repository path
|
||||
bootstrap github --owner=<organization> --repository=<repo name> --path=dev-cluster
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name> --path=dev-cluster
|
||||
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
tk bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise
|
||||
bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
|
||||
`,
|
||||
RunE: bootstrapGitHubCmdRun,
|
||||
}
|
||||
@@ -175,7 +175,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if isInstall {
|
||||
// apply install manifests
|
||||
logger.Actionf("installing components in %s namespace", namespace)
|
||||
if err := applyInstallManifests(ctx, manifest, components); err != nil {
|
||||
if err := applyInstallManifests(ctx, manifest, bootstrapComponents); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("install completed")
|
||||
|
||||
@@ -42,16 +42,16 @@ the bootstrap command will perform an upgrade if needed.`,
|
||||
export GITLAB_TOKEN=<my-token>
|
||||
|
||||
# Run bootstrap for a private repo owned by a GitLab group
|
||||
bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
tk bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
|
||||
# Run bootstrap for a repository path
|
||||
bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster
|
||||
tk bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster
|
||||
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
tk bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
|
||||
# Run bootstrap for a private repo hosted on a GitLab server
|
||||
bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
|
||||
tk bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
|
||||
`,
|
||||
RunE: bootstrapGitLabCmdRun,
|
||||
}
|
||||
@@ -153,7 +153,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if isInstall {
|
||||
// apply install manifests
|
||||
logger.Actionf("installing components in %s namespace", namespace)
|
||||
if err := applyInstallManifests(ctx, manifest, components); err != nil {
|
||||
if err := applyInstallManifests(ctx, manifest, bootstrapComponents); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("install completed")
|
||||
|
||||
@@ -35,22 +35,24 @@ var checkCmd = &cobra.Command{
|
||||
Long: `The check command will perform a series of checks to validate that
|
||||
the local environment is configured correctly and if the installed components are healthy.`,
|
||||
Example: ` # Run pre-installation checks
|
||||
check --pre
|
||||
tk check --pre
|
||||
|
||||
# Run installation checks
|
||||
check
|
||||
tk check
|
||||
`,
|
||||
RunE: runCheckCmd,
|
||||
}
|
||||
|
||||
var (
|
||||
checkPre bool
|
||||
checkPre bool
|
||||
checkComponents []string
|
||||
)
|
||||
|
||||
func init() {
|
||||
checkCmd.Flags().BoolVarP(&checkPre, "pre", "", false,
|
||||
"only run pre-installation checks")
|
||||
|
||||
checkCmd.Flags().StringSliceVar(&checkComponents, "components", defaultComponents,
|
||||
"list of components, accepts comma-separated values")
|
||||
rootCmd.AddCommand(checkCmd)
|
||||
}
|
||||
|
||||
@@ -65,7 +67,7 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
|
||||
checkFailed = true
|
||||
}
|
||||
|
||||
if !kubernetesCheck(">=1.14.0") {
|
||||
if !kubernetesCheck(">=1.16.0") {
|
||||
checkFailed = true
|
||||
}
|
||||
|
||||
@@ -158,7 +160,7 @@ func componentsCheck() bool {
|
||||
defer cancel()
|
||||
|
||||
ok := true
|
||||
for _, deployment := range components {
|
||||
for _, deployment := range checkComponents {
|
||||
command := fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
||||
namespace, deployment, timeout.String())
|
||||
if output, err := utils.execCommand(ctx, ModeCapture, command); err != nil {
|
||||
|
||||
256
cmd/tk/create_helmrelease.go
Normal file
256
cmd/tk/create_helmrelease.go
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
)
|
||||
|
||||
var createHelmReleaseCmd = &cobra.Command{
|
||||
Use: "helmrelease [name]",
|
||||
Aliases: []string{"hr"},
|
||||
Short: "Create or update a HelmRelease resource",
|
||||
Long: "The helmrelease create command generates a HelmRelease resource for a given HelmRepository source.",
|
||||
Example: ` # Create a HelmRelease from a source
|
||||
tk create hr podinfo \
|
||||
--interval=10m \
|
||||
--release-name=podinfo \
|
||||
--target-namespace=default \
|
||||
--source=podinfo \
|
||||
--chart-name=podinfo \
|
||||
--chart-version=">4.0.0"
|
||||
|
||||
# Create a HelmRelease with values for a local YAML file
|
||||
tk create hr podinfo \
|
||||
--target-namespace=default \
|
||||
--source=podinfo \
|
||||
--chart-name=podinfo \
|
||||
--chart-version=4.0.5 \
|
||||
--values=./my-values.yaml
|
||||
|
||||
# Create a HelmRelease definition on disk without applying it on the cluster
|
||||
tk create hr podinfo \
|
||||
--target-namespace=default \
|
||||
--source=podinfo \
|
||||
--chart-name=podinfo \
|
||||
--chart-version=4.0.5 \
|
||||
--values=./values.yaml \
|
||||
--export > podinfo-release.yaml
|
||||
`,
|
||||
RunE: createHelmReleaseCmdRun,
|
||||
}
|
||||
|
||||
var (
|
||||
hrName string
|
||||
hrSource string
|
||||
hrDependsOn []string
|
||||
hrChartName string
|
||||
hrChartVersion string
|
||||
hrTargetNamespace string
|
||||
hrValuesFile string
|
||||
)
|
||||
|
||||
func init() {
|
||||
createHelmReleaseCmd.Flags().StringVar(&hrName, "release-name", "", "name used for the Helm release, defaults to a composition of '<target-namespace>-<hr-name>'")
|
||||
createHelmReleaseCmd.Flags().StringVar(&hrSource, "source", "", "HelmRepository name")
|
||||
createHelmReleaseCmd.Flags().StringVar(&hrChartName, "chart-name", "", "Helm chart name")
|
||||
createHelmReleaseCmd.Flags().StringVar(&hrChartVersion, "chart-version", "", "Helm chart version, accepts semver range")
|
||||
createHelmReleaseCmd.Flags().StringArrayVar(&hrDependsOn, "depends-on", nil, "HelmReleases that must be ready before this release can be installed")
|
||||
createHelmReleaseCmd.Flags().StringVar(&hrTargetNamespace, "target-namespace", "", "namespace to install this release, defaults to the HelmRelease namespace")
|
||||
createHelmReleaseCmd.Flags().StringVar(&hrValuesFile, "values", "", "local path to the values.yaml file")
|
||||
createCmd.AddCommand(createHelmReleaseCmd)
|
||||
}
|
||||
|
||||
func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("release name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
if hrSource == "" {
|
||||
return fmt.Errorf("source is required")
|
||||
}
|
||||
if hrChartName == "" {
|
||||
return fmt.Errorf("chart name is required")
|
||||
}
|
||||
if hrChartVersion == "" {
|
||||
return fmt.Errorf("chart version is required")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !export {
|
||||
logger.Generatef("generating release")
|
||||
}
|
||||
|
||||
helmRelease := helmv2.HelmRelease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: helmv2.HelmReleaseSpec{
|
||||
ReleaseName: hrName,
|
||||
DependsOn: hrDependsOn,
|
||||
Interval: metav1.Duration{
|
||||
Duration: interval,
|
||||
},
|
||||
TargetNamespace: hrTargetNamespace,
|
||||
Chart: helmv2.HelmChartTemplate{
|
||||
Name: hrChartName,
|
||||
Version: hrChartVersion,
|
||||
SourceRef: helmv2.CrossNamespaceObjectReference{
|
||||
Kind: sourcev1.HelmRepositoryKind,
|
||||
Name: hrSource,
|
||||
},
|
||||
},
|
||||
Suspend: false,
|
||||
},
|
||||
}
|
||||
|
||||
if hrValuesFile != "" {
|
||||
data, err := ioutil.ReadFile(hrValuesFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading values from %s failed: %w", hrValuesFile, err)
|
||||
}
|
||||
|
||||
json, err := yaml.YAMLToJSON(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting values to JSON from %s failed: %w", hrValuesFile, err)
|
||||
}
|
||||
|
||||
helmRelease.Spec.Values = apiextensionsv1.JSON{Raw: json}
|
||||
}
|
||||
|
||||
if export {
|
||||
return exportHelmRelease(helmRelease)
|
||||
}
|
||||
|
||||
logger.Actionf("applying release")
|
||||
if err := upsertHelmRelease(ctx, kubeClient, helmRelease); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Waitingf("waiting for reconciliation")
|
||||
chartName := fmt.Sprintf("%s-%s", namespace, name)
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isHelmChartReady(ctx, kubeClient, chartName, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isHelmReleaseReady(ctx, kubeClient, name, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("release %s is ready", name)
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return fmt.Errorf("release failed: %w", err)
|
||||
}
|
||||
|
||||
if helmRelease.Status.LastAppliedRevision != "" {
|
||||
logger.Successf("applied revision %s", helmRelease.Status.LastAppliedRevision)
|
||||
} else {
|
||||
return fmt.Errorf("reconciliation failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func upsertHelmRelease(ctx context.Context, kubeClient client.Client, helmRelease helmv2.HelmRelease) error {
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: helmRelease.GetNamespace(),
|
||||
Name: helmRelease.GetName(),
|
||||
}
|
||||
|
||||
var existing helmv2.HelmRelease
|
||||
err := kubeClient.Get(ctx, namespacedName, &existing)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
if err := kubeClient.Create(ctx, &helmRelease); err != nil {
|
||||
return err
|
||||
} else {
|
||||
logger.Successf("release created")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
existing.Spec = helmRelease.Spec
|
||||
if err := kubeClient.Update(ctx, &existing); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("release updated")
|
||||
return nil
|
||||
}
|
||||
|
||||
func isHelmChartReady(ctx context.Context, kubeClient client.Client, name, namespace string) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
var helmChart sourcev1.HelmChart
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
err := kubeClient.Get(ctx, namespacedName, &helmChart)
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, condition := range helmChart.Status.Conditions {
|
||||
if condition.Type == helmv2.ReadyCondition {
|
||||
if condition.Status == corev1.ConditionTrue {
|
||||
return true, nil
|
||||
} else if condition.Status == corev1.ConditionFalse {
|
||||
return false, fmt.Errorf(condition.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
@@ -40,32 +40,32 @@ var createKsCmd = &cobra.Command{
|
||||
Short: "Create or update a Kustomization resource",
|
||||
Long: "The kustomization source create command generates a Kustomize resource for a given GitRepository source.",
|
||||
Example: ` # Create a Kustomization resource from a source at a given path
|
||||
create kustomization contour \
|
||||
tk create kustomization contour \
|
||||
--source=contour \
|
||||
--path="./examples/contour/" \
|
||||
--prune=true \
|
||||
--interval=10m \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--health-check="Deployment/contour.projectcontour" \
|
||||
--health-check="DaemonSet/envoy.projectcontour" \
|
||||
--health-check-timeout=3m
|
||||
|
||||
# Create a Kustomization resource that depends on the previous one
|
||||
create kustomization webapp \
|
||||
tk create kustomization webapp \
|
||||
--depends-on=contour \
|
||||
--source=webapp \
|
||||
--path="./deploy/overlays/dev" \
|
||||
--prune=true \
|
||||
--interval=5m \
|
||||
--validate=client
|
||||
--validation=client
|
||||
|
||||
# Create a Kustomization resource that runs under a service account
|
||||
create kustomization webapp \
|
||||
tk create kustomization webapp \
|
||||
--source=webapp \
|
||||
--path="./deploy/overlays/staging" \
|
||||
--prune=true \
|
||||
--interval=5m \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--sa-name=reconclier \
|
||||
--sa-namespace=staging
|
||||
`,
|
||||
@@ -77,7 +77,7 @@ var (
|
||||
ksPath string
|
||||
ksPrune bool
|
||||
ksDependsOn []string
|
||||
ksValidate string
|
||||
ksValidation string
|
||||
ksHealthCheck []string
|
||||
ksHealthTimeout time.Duration
|
||||
ksSAName string
|
||||
@@ -90,7 +90,7 @@ func init() {
|
||||
createKsCmd.Flags().BoolVar(&ksPrune, "prune", false, "enable garbage collection")
|
||||
createKsCmd.Flags().StringArrayVar(&ksHealthCheck, "health-check", nil, "workload to be included in the health assessment, in the format '<kind>/<name>.<namespace>'")
|
||||
createKsCmd.Flags().DurationVar(&ksHealthTimeout, "health-check-timeout", 2*time.Minute, "timeout of health checking operations")
|
||||
createKsCmd.Flags().StringVar(&ksValidate, "validate", "", "validate the manifests before applying them on the cluster, can be 'client' or 'server'")
|
||||
createKsCmd.Flags().StringVar(&ksValidation, "validation", "", "validate the manifests before applying them on the cluster, can be 'client' or 'server'")
|
||||
createKsCmd.Flags().StringArrayVar(&ksDependsOn, "depends-on", nil, "Kustomization that must be ready before this Kustomization can be applied")
|
||||
createKsCmd.Flags().StringVar(&ksSAName, "sa-name", "", "service account name")
|
||||
createKsCmd.Flags().StringVar(&ksSANamespace, "sa-namespace", "", "service account namespace")
|
||||
@@ -113,19 +113,10 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
return fmt.Errorf("path must begin with ./")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !export {
|
||||
logger.Generatef("generating kustomization")
|
||||
}
|
||||
|
||||
emptyAPIGroup := ""
|
||||
kustomization := kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
@@ -138,13 +129,12 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
},
|
||||
Path: ksPath,
|
||||
Prune: ksPrune,
|
||||
SourceRef: corev1.TypedLocalObjectReference{
|
||||
APIGroup: &emptyAPIGroup,
|
||||
Kind: "GitRepository",
|
||||
Name: ksSource,
|
||||
SourceRef: kustomizev1.CrossNamespaceObjectReference{
|
||||
Kind: sourcev1.GitRepositoryKind,
|
||||
Name: ksSource,
|
||||
},
|
||||
Suspend: false,
|
||||
Validation: ksValidate,
|
||||
Validation: ksValidation,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -192,6 +182,14 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
return exportKs(kustomization)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("applying kustomization")
|
||||
if err := upsertKustomization(ctx, kubeClient, kustomization); err != nil {
|
||||
return err
|
||||
|
||||
@@ -46,35 +46,35 @@ The create source git command generates a GitRepository resource and waits for i
|
||||
For Git over SSH, host and SSH keys are automatically generated and stored in a Kubernetes secret.
|
||||
For private Git repositories, the basic authentication credentials are stored in a Kubernetes secret.`,
|
||||
Example: ` # Create a source from a public Git repository master branch
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--branch=master
|
||||
|
||||
# Create a source from a Git repository pinned to specific git tag
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--tag="3.2.3"
|
||||
|
||||
# Create a source from a public Git repository tag that matches a semver range
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--tag-semver=">=3.2.0 <3.3.0"
|
||||
|
||||
# Create a source from a Git repository using SSH authentication
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=ssh://git@github.com/stefanprodan/podinfo \
|
||||
--branch=master
|
||||
|
||||
# Create a source from a Git repository using SSH authentication and an
|
||||
# ECDSA P-521 curve public key
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=ssh://git@github.com/stefanprodan/podinfo \
|
||||
--branch=master \
|
||||
--ssh-key-algorithm=ecdsa \
|
||||
--ssh-ecdsa-curve=p521
|
||||
|
||||
# Create a source from a Git repository using basic authentication
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--username=username \
|
||||
--password=password
|
||||
@@ -115,7 +115,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
name := args[0]
|
||||
|
||||
if sourceGitURL == "" {
|
||||
return fmt.Errorf("git-url is required")
|
||||
return fmt.Errorf("url is required")
|
||||
}
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", name)
|
||||
@@ -129,14 +129,6 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
return fmt.Errorf("git URL parse failed: %w", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gitRepository := sourcev1.GitRepository{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
@@ -163,6 +155,14 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
return exportGit(gitRepository)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
withAuth := false
|
||||
// TODO(hidde): move all auth prep to separate func?
|
||||
if u.Scheme == "ssh" {
|
||||
|
||||
259
cmd/tk/create_source_helm.go
Normal file
259
cmd/tk/create_source_helm.go
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
"github.com/spf13/cobra"
|
||||
"io/ioutil"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"net/url"
|
||||
"os"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var createSourceHelmCmd = &cobra.Command{
|
||||
Use: "helm [name]",
|
||||
Short: "Create or update a HelmRepository source",
|
||||
Long: `
|
||||
The create source helm command generates a HelmRepository resource and waits for it to fetch the index.
|
||||
For private Helm repositories, the basic authentication credentials are stored in a Kubernetes secret.`,
|
||||
Example: ` # Create a source from a public Helm repository
|
||||
tk create source helm podinfo \
|
||||
--url=https://stefanprodan.github.io/podinfo \
|
||||
--interval=10m
|
||||
|
||||
# Create a source from a Helm repository using basic authentication
|
||||
tk create source helm podinfo \
|
||||
--url=https://stefanprodan.github.io/podinfo \
|
||||
--username=username \
|
||||
--password=password
|
||||
|
||||
# Create a source from a Helm repository using TLS authentication
|
||||
tk create source helm podinfo \
|
||||
--url=https://stefanprodan.github.io/podinfo \
|
||||
--cert-file=./cert.crt \
|
||||
--key-file=./key.crt \
|
||||
--ca-file=./ca.crt
|
||||
`,
|
||||
RunE: createSourceHelmCmdRun,
|
||||
}
|
||||
|
||||
var (
|
||||
sourceHelmURL string
|
||||
sourceHelmUsername string
|
||||
sourceHelmPassword string
|
||||
sourceHelmCertFile string
|
||||
sourceHelmKeyFile string
|
||||
sourceHelmCAFile string
|
||||
)
|
||||
|
||||
func init() {
|
||||
createSourceHelmCmd.Flags().StringVar(&sourceHelmURL, "url", "", "Helm repository address")
|
||||
createSourceHelmCmd.Flags().StringVarP(&sourceHelmUsername, "username", "u", "", "basic authentication username")
|
||||
createSourceHelmCmd.Flags().StringVarP(&sourceHelmPassword, "password", "p", "", "basic authentication password")
|
||||
createSourceHelmCmd.Flags().StringVar(&sourceHelmCertFile, "cert-file", "", "TLS authentication cert file path")
|
||||
createSourceHelmCmd.Flags().StringVar(&sourceHelmKeyFile, "key-file", "", "TLS authentication key file path")
|
||||
createSourceHelmCmd.Flags().StringVar(&sourceHelmCAFile, "ca-file", "", "TLS authentication CA file path")
|
||||
|
||||
createSourceCmd.AddCommand(createSourceHelmCmd)
|
||||
}
|
||||
|
||||
func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
secretName := fmt.Sprintf("helm-%s", name)
|
||||
|
||||
if sourceHelmURL == "" {
|
||||
return fmt.Errorf("url is required")
|
||||
}
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
if _, err := url.Parse(sourceHelmURL); err != nil {
|
||||
return fmt.Errorf("url parse failed: %w", err)
|
||||
}
|
||||
|
||||
helmRepository := sourcev1.HelmRepository{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: sourcev1.HelmRepositorySpec{
|
||||
URL: sourceHelmURL,
|
||||
Interval: metav1.Duration{
|
||||
Duration: interval,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if export {
|
||||
return exportHelmRepository(helmRepository)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Generatef("generating source")
|
||||
|
||||
secret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
StringData: map[string]string{},
|
||||
}
|
||||
|
||||
if sourceHelmUsername != "" && sourceHelmPassword != "" {
|
||||
secret.StringData["username"] = sourceHelmUsername
|
||||
secret.StringData["password"] = sourceHelmPassword
|
||||
}
|
||||
|
||||
if sourceHelmCertFile != "" && sourceHelmKeyFile != "" {
|
||||
cert, err := ioutil.ReadFile(sourceHelmCertFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read repository cert file '%s': %w", sourceHelmCertFile, err)
|
||||
}
|
||||
secret.StringData["certFile"] = string(cert)
|
||||
|
||||
key, err := ioutil.ReadFile(sourceHelmKeyFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read repository key file '%s': %w", sourceHelmKeyFile, err)
|
||||
}
|
||||
secret.StringData["keyFile"] = string(key)
|
||||
}
|
||||
|
||||
if sourceHelmCAFile != "" {
|
||||
ca, err := ioutil.ReadFile(sourceHelmCAFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read repository CA file '%s': %w", sourceHelmCAFile, err)
|
||||
}
|
||||
secret.StringData["caFile"] = string(ca)
|
||||
}
|
||||
|
||||
if len(secret.StringData) > 0 {
|
||||
logger.Actionf("applying secret with repository credentials")
|
||||
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
|
||||
return err
|
||||
}
|
||||
helmRepository.Spec.SecretRef = &corev1.LocalObjectReference{
|
||||
Name: secretName,
|
||||
}
|
||||
logger.Successf("authentication configured")
|
||||
}
|
||||
|
||||
logger.Actionf("applying source")
|
||||
if err := upsertHelmRepository(ctx, kubeClient, helmRepository); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Waitingf("waiting for index download")
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isHelmRepositoryReady(ctx, kubeClient, name, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("index download completed")
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRepository)
|
||||
if err != nil {
|
||||
return fmt.Errorf("helm index failed: %w", err)
|
||||
}
|
||||
|
||||
if helmRepository.Status.Artifact != nil {
|
||||
logger.Successf("fetched revision: %s", helmRepository.Status.Artifact.Revision)
|
||||
} else {
|
||||
return fmt.Errorf("index download failed, artifact not found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func upsertHelmRepository(ctx context.Context, kubeClient client.Client, helmRepository sourcev1.HelmRepository) error {
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: helmRepository.GetNamespace(),
|
||||
Name: helmRepository.GetName(),
|
||||
}
|
||||
|
||||
var existing sourcev1.HelmRepository
|
||||
err := kubeClient.Get(ctx, namespacedName, &existing)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
if err := kubeClient.Create(ctx, &helmRepository); err != nil {
|
||||
return err
|
||||
} else {
|
||||
logger.Successf("source created")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
existing.Spec = helmRepository.Spec
|
||||
if err := kubeClient.Update(ctx, &existing); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("source updated")
|
||||
return nil
|
||||
}
|
||||
|
||||
func exportHelmRepository(source sourcev1.HelmRepository) error {
|
||||
gvk := sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)
|
||||
export := sourcev1.HelmRepository{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: gvk.Kind,
|
||||
APIVersion: gvk.GroupVersion().String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: source.Name,
|
||||
Namespace: source.Namespace,
|
||||
},
|
||||
Spec: source.Spec,
|
||||
}
|
||||
|
||||
data, err := yaml.Marshal(export)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("---")
|
||||
fmt.Println(string(data))
|
||||
return nil
|
||||
}
|
||||
91
cmd/tk/delete_helmrelease.go
Normal file
91
cmd/tk/delete_helmrelease.go
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/manifoldco/promptui"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
)
|
||||
|
||||
var deleteHelmReleaseCmd = &cobra.Command{
|
||||
Use: "helmrelease [name]",
|
||||
Aliases: []string{"hr"},
|
||||
Short: "Delete a HelmRelease resource",
|
||||
Long: "The delete helmrelease command removes the given HelmRelease from the cluster.",
|
||||
Example: ` # Delete a Helm release and the Kubernetes resources created by it
|
||||
tk delete hr podinfo
|
||||
`,
|
||||
RunE: deleteHelmReleaseCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
deleteCmd.AddCommand(deleteHelmReleaseCmd)
|
||||
}
|
||||
|
||||
func deleteHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("release name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
var helmRelease helmv2.HelmRelease
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !deleteSilent {
|
||||
if !helmRelease.Spec.Suspend {
|
||||
logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s Helm release!", name)
|
||||
}
|
||||
prompt := promptui.Prompt{
|
||||
Label: "Are you sure you want to delete this Helm release",
|
||||
IsConfirm: true,
|
||||
}
|
||||
if _, err := prompt.Run(); err != nil {
|
||||
return fmt.Errorf("aborting")
|
||||
}
|
||||
}
|
||||
|
||||
logger.Actionf("deleting release %s in %s namespace", name, namespace)
|
||||
err = kubeClient.Delete(ctx, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("release deleted")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -31,7 +31,10 @@ var deleteKsCmd = &cobra.Command{
|
||||
Aliases: []string{"ks"},
|
||||
Short: "Delete a Kustomization resource",
|
||||
Long: "The delete kustomization command deletes the given Kustomization from the cluster.",
|
||||
RunE: deleteKsCmdRun,
|
||||
Example: ` # Delete a kustomization and the Kubernetes resources created by it
|
||||
tk delete kustomization podinfo
|
||||
`,
|
||||
RunE: deleteKsCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -30,7 +30,10 @@ var deleteSourceGitCmd = &cobra.Command{
|
||||
Use: "git [name]",
|
||||
Short: "Delete a GitRepository source",
|
||||
Long: "The delete source git command deletes the given GitRepository from the cluster.",
|
||||
RunE: deleteSourceGitCmdRun,
|
||||
Example: ` # Delete a Git repository
|
||||
tk delete source git podinfo
|
||||
`,
|
||||
RunE: deleteSourceGitCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
86
cmd/tk/delete_source_helm.go
Normal file
86
cmd/tk/delete_source_helm.go
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
"github.com/manifoldco/promptui"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
var deleteSourceHelmCmd = &cobra.Command{
|
||||
Use: "helm [name]",
|
||||
Short: "Delete a HelmRepository source",
|
||||
Long: "The delete source helm command deletes the given HelmRepository from the cluster.",
|
||||
Example: ` # Delete a Helm repository
|
||||
tk delete source helm podinfo
|
||||
`,
|
||||
RunE: deleteSourceHelmCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
deleteSourceCmd.AddCommand(deleteSourceHelmCmd)
|
||||
}
|
||||
|
||||
func deleteSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
var helmRepository sourcev1.HelmRepository
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRepository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !deleteSilent {
|
||||
prompt := promptui.Prompt{
|
||||
Label: "Are you sure you want to delete this source",
|
||||
IsConfirm: true,
|
||||
}
|
||||
if _, err := prompt.Run(); err != nil {
|
||||
return fmt.Errorf("aborting")
|
||||
}
|
||||
}
|
||||
|
||||
logger.Actionf("deleting source %s in %s namespace", name, namespace)
|
||||
err = kubeClient.Delete(ctx, &helmRepository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("source deleted")
|
||||
|
||||
return nil
|
||||
}
|
||||
118
cmd/tk/export_helmrelease.go
Normal file
118
cmd/tk/export_helmrelease.go
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
)
|
||||
|
||||
var exportHelmReleaseCmd = &cobra.Command{
|
||||
Use: "helmrelease [name]",
|
||||
Aliases: []string{"hr"},
|
||||
Short: "Export HelmRelease resources in YAML format",
|
||||
Long: "The export helmrelease command exports one or all HelmRelease resources in YAML format.",
|
||||
Example: ` # Export all HelmRelease resources
|
||||
tk export helmrelease --all > kustomizations.yaml
|
||||
|
||||
# Export a HelmRelease
|
||||
tk export hr my-app > app-release.yaml
|
||||
`,
|
||||
RunE: exportHelmReleaseCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
exportCmd.AddCommand(exportHelmReleaseCmd)
|
||||
}
|
||||
|
||||
func exportHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if !exportAll && len(args) < 1 {
|
||||
return fmt.Errorf("name is required")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exportAll {
|
||||
var list helmv2.HelmReleaseList
|
||||
err = kubeClient.List(ctx, &list, client.InNamespace(namespace))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(list.Items) == 0 {
|
||||
logger.Failuref("no kustomizations found in %s namespace", namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, helmRelease := range list.Items {
|
||||
if err := exportHelmRelease(helmRelease); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
name := args[0]
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
var helmRelease helmv2.HelmRelease
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return exportHelmRelease(helmRelease)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func exportHelmRelease(helmRelease helmv2.HelmRelease) error {
|
||||
gvk := helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)
|
||||
export := helmv2.HelmRelease{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: gvk.Kind,
|
||||
APIVersion: gvk.GroupVersion().String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: helmRelease.Name,
|
||||
Namespace: helmRelease.Namespace,
|
||||
},
|
||||
Spec: helmRelease.Spec,
|
||||
}
|
||||
|
||||
data, err := yaml.Marshal(export)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("---")
|
||||
fmt.Println(string(data))
|
||||
return nil
|
||||
}
|
||||
@@ -34,10 +34,10 @@ var exportKsCmd = &cobra.Command{
|
||||
Short: "Export Kustomization resources in YAML format",
|
||||
Long: "The export kustomization command exports one or all Kustomization resources in YAML format.",
|
||||
Example: ` # Export all Kustomization resources
|
||||
export kustomization --all > kustomizations.yaml
|
||||
tk export kustomization --all > kustomizations.yaml
|
||||
|
||||
# Export a Kustomization
|
||||
export kustomization my-app > kustomization.yaml
|
||||
tk export kustomization my-app > kustomization.yaml
|
||||
`,
|
||||
RunE: exportKsCmdRun,
|
||||
}
|
||||
|
||||
@@ -34,10 +34,10 @@ var exportSourceGitCmd = &cobra.Command{
|
||||
Short: "Export GitRepository sources in YAML format",
|
||||
Long: "The export source git command exports on or all GitRepository sources in YAML format.",
|
||||
Example: ` # Export all GitRepository sources
|
||||
export source git --all > sources.yaml
|
||||
tk export source git --all > sources.yaml
|
||||
|
||||
# Export a GitRepository source including the SSH key pair or basic auth credentials
|
||||
export source git my-private-repo --with-credentials > source.yaml
|
||||
tk export source git my-private-repo --with-credentials > source.yaml
|
||||
`,
|
||||
RunE: exportSourceGitCmdRun,
|
||||
}
|
||||
@@ -48,7 +48,7 @@ func init() {
|
||||
|
||||
func exportSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if !exportAll && len(args) < 1 {
|
||||
return fmt.Errorf("kustomization name is required")
|
||||
return fmt.Errorf("name is required")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
@@ -103,7 +103,7 @@ func exportSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
func exportGit(source sourcev1.GitRepository) error {
|
||||
gvk := sourcev1.GroupVersion.WithKind("GitRepository")
|
||||
gvk := sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)
|
||||
export := sourcev1.GitRepository{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: gvk.Kind,
|
||||
|
||||
139
cmd/tk/export_source_helm.go
Normal file
139
cmd/tk/export_source_helm.go
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var exportSourceHelmCmd = &cobra.Command{
|
||||
Use: "helm [name]",
|
||||
Short: "Export HelmRepository sources in YAML format",
|
||||
Long: "The export source git command exports on or all HelmRepository sources in YAML format.",
|
||||
Example: ` # Export all HelmRepository sources
|
||||
tk export source helm --all > sources.yaml
|
||||
|
||||
# Export a HelmRepository source including the basic auth credentials
|
||||
tk export source helm my-private-repo --with-credentials > source.yaml
|
||||
`,
|
||||
RunE: exportSourceHelmCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
exportSourceCmd.AddCommand(exportSourceHelmCmd)
|
||||
}
|
||||
|
||||
func exportSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if !exportAll && len(args) < 1 {
|
||||
return fmt.Errorf("name is required")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exportAll {
|
||||
var list sourcev1.HelmRepositoryList
|
||||
err = kubeClient.List(ctx, &list, client.InNamespace(namespace))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(list.Items) == 0 {
|
||||
logger.Failuref("no source found in %s namespace", namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, repository := range list.Items {
|
||||
if err := exportHelmRepository(repository); err != nil {
|
||||
return err
|
||||
}
|
||||
if exportSourceWithCred {
|
||||
if err := exportHelmCredentials(ctx, kubeClient, repository); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
name := args[0]
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
var repository sourcev1.HelmRepository
|
||||
err = kubeClient.Get(ctx, namespacedName, &repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := exportHelmRepository(repository); err != nil {
|
||||
return err
|
||||
}
|
||||
if exportSourceWithCred {
|
||||
return exportHelmCredentials(ctx, kubeClient, repository)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func exportHelmCredentials(ctx context.Context, kubeClient client.Client, source sourcev1.HelmRepository) error {
|
||||
if source.Spec.SecretRef != nil {
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: source.Namespace,
|
||||
Name: source.Spec.SecretRef.Name,
|
||||
}
|
||||
var cred corev1.Secret
|
||||
err := kubeClient.Get(ctx, namespacedName, &cred)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve secret %s, error: %w", namespacedName.Name, err)
|
||||
}
|
||||
|
||||
exported := corev1.Secret{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Secret",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespacedName.Name,
|
||||
Namespace: namespacedName.Namespace,
|
||||
},
|
||||
Data: cred.Data,
|
||||
Type: cred.Type,
|
||||
}
|
||||
|
||||
data, err := yaml.Marshal(exported)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("---")
|
||||
fmt.Println(string(data))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
90
cmd/tk/get_helmrelease.go
Normal file
90
cmd/tk/get_helmrelease.go
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
)
|
||||
|
||||
var getHelmReleaseCmd = &cobra.Command{
|
||||
Use: "helmreleases",
|
||||
Aliases: []string{"hr"},
|
||||
Short: "Get HelmRelease statuses",
|
||||
Long: "The get helmreleases command prints the statuses of the resources.",
|
||||
Example: ` # List all Helm releases and their status
|
||||
tk get helmreleases
|
||||
`,
|
||||
RunE: getHelmReleaseCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
getCmd.AddCommand(getHelmReleaseCmd)
|
||||
}
|
||||
|
||||
func getHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var list helmv2.HelmReleaseList
|
||||
err = kubeClient.List(ctx, &list, client.InNamespace(namespace))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(list.Items) == 0 {
|
||||
logger.Failuref("no releases found in %s namespace", namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, helmRelease := range list.Items {
|
||||
if helmRelease.Spec.Suspend {
|
||||
logger.Successf("%s is suspended", helmRelease.GetName())
|
||||
continue
|
||||
}
|
||||
isInitialized := false
|
||||
for _, condition := range helmRelease.Status.Conditions {
|
||||
if condition.Type == helmv2.ReadyCondition {
|
||||
if condition.Status != corev1.ConditionFalse {
|
||||
if helmRelease.Status.LastAppliedRevision != "" {
|
||||
logger.Successf("%s last applied revision %s", helmRelease.GetName(), helmRelease.Status.LastAppliedRevision)
|
||||
} else {
|
||||
logger.Successf("%s reconciling", helmRelease.GetName())
|
||||
}
|
||||
} else {
|
||||
logger.Failuref("%s %s", helmRelease.GetName(), condition.Message)
|
||||
}
|
||||
isInitialized = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isInitialized {
|
||||
logger.Failuref("%s is not ready", helmRelease.GetName())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -28,9 +28,12 @@ import (
|
||||
var getKsCmd = &cobra.Command{
|
||||
Use: "kustomizations",
|
||||
Aliases: []string{"ks"},
|
||||
Short: "Get Kustomization source statuses",
|
||||
Short: "Get Kustomization statuses",
|
||||
Long: "The get kustomizations command prints the statuses of the resources.",
|
||||
RunE: getKsCmdRun,
|
||||
Example: ` # List all kustomizations and their status
|
||||
tk get kustomizations
|
||||
`,
|
||||
RunE: getKsCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -29,7 +29,10 @@ var getSourceGitCmd = &cobra.Command{
|
||||
Use: "git",
|
||||
Short: "Get GitRepository source statuses",
|
||||
Long: "The get sources git command prints the status of the GitRepository sources.",
|
||||
RunE: getSourceGitCmdRun,
|
||||
Example: ` # List all Git repositories and their status
|
||||
tk get sources git
|
||||
`,
|
||||
RunE: getSourceGitCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
80
cmd/tk/get_source_helm.go
Normal file
80
cmd/tk/get_source_helm.go
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
var getSourceHelmCmd = &cobra.Command{
|
||||
Use: "helm",
|
||||
Short: "Get HelmRepository source statuses",
|
||||
Long: "The get sources helm command prints the status of the HelmRepository sources.",
|
||||
Example: ` # List all Helm repositories and their status
|
||||
tk get sources helm
|
||||
`,
|
||||
RunE: getSourceHelmCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
getSourceCmd.AddCommand(getSourceHelmCmd)
|
||||
}
|
||||
|
||||
func getSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var list sourcev1.HelmRepositoryList
|
||||
err = kubeClient.List(ctx, &list, client.InNamespace(namespace))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(list.Items) == 0 {
|
||||
logger.Failuref("no sources found in %s namespace", namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, source := range list.Items {
|
||||
isInitialized := false
|
||||
for _, condition := range source.Status.Conditions {
|
||||
if condition.Type == sourcev1.ReadyCondition {
|
||||
if condition.Status != corev1.ConditionFalse {
|
||||
logger.Successf("%s last fetched revision: %s", source.GetName(), source.Status.Artifact.Revision)
|
||||
} else {
|
||||
logger.Failuref("%s %s", source.GetName(), condition.Message)
|
||||
}
|
||||
isInitialized = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isInitialized {
|
||||
logger.Failuref("%s is not ready", source.GetName())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -19,11 +19,14 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/fluxcd/pkg/untar"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/api/filesys"
|
||||
@@ -36,30 +39,45 @@ var installCmd = &cobra.Command{
|
||||
Long: `The install command deploys the toolkit components in the specified namespace.
|
||||
If a previous version is installed, then an in-place upgrade will be performed.`,
|
||||
Example: ` # Install the latest version in the gitops-systems namespace
|
||||
install --version=master --namespace=gitops-systems
|
||||
tk install --version=latest --namespace=gitops-systems
|
||||
|
||||
# Dry-run install for a specific version and a series of components
|
||||
install --dry-run --version=0.0.1 --components="source-controller,kustomize-controller"
|
||||
tk install --dry-run --version=v0.0.7 --components="source-controller,kustomize-controller"
|
||||
|
||||
# Dry-run install with manifests preview
|
||||
install --dry-run --verbose
|
||||
tk install --dry-run --verbose
|
||||
|
||||
# Write install manifests to file
|
||||
tk install --export > gitops-system.yaml
|
||||
`,
|
||||
RunE: installCmdRun,
|
||||
}
|
||||
|
||||
var (
|
||||
installDryRun bool
|
||||
installManifestsPath string
|
||||
installVersion string
|
||||
installExport bool
|
||||
installDryRun bool
|
||||
installManifestsPath string
|
||||
installVersion string
|
||||
installComponents []string
|
||||
installRegistry string
|
||||
installImagePullSecret string
|
||||
)
|
||||
|
||||
func init() {
|
||||
installCmd.Flags().BoolVar(&installExport, "export", false,
|
||||
"write the install manifests to stdout and exit")
|
||||
installCmd.Flags().BoolVarP(&installDryRun, "dry-run", "", false,
|
||||
"only print the object that would be applied")
|
||||
installCmd.Flags().StringVarP(&installVersion, "version", "v", "master",
|
||||
"toolkit tag or branch")
|
||||
installCmd.Flags().StringVarP(&installManifestsPath, "manifests", "", "",
|
||||
installCmd.Flags().StringVarP(&installVersion, "version", "v", defaultVersion,
|
||||
"toolkit version")
|
||||
installCmd.Flags().StringSliceVar(&installComponents, "components", defaultComponents,
|
||||
"list of components, accepts comma-separated values")
|
||||
installCmd.Flags().StringVar(&installManifestsPath, "manifests", "",
|
||||
"path to the manifest directory, dev only")
|
||||
installCmd.Flags().StringVar(&installRegistry, "registry", "docker.io/fluxcd",
|
||||
"container registry where the toolkit images are published")
|
||||
installCmd.Flags().StringVar(&installImagePullSecret, "image-pull-secret", "",
|
||||
"Kubernetes secret name used for pulling the toolkit images from a private registry")
|
||||
rootCmd.AddCommand(installCmd)
|
||||
}
|
||||
|
||||
@@ -81,9 +99,11 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
logger.Generatef("generating manifests")
|
||||
if !installExport {
|
||||
logger.Generatef("generating manifests")
|
||||
}
|
||||
if kustomizePath == "" {
|
||||
err = genInstallManifests(installVersion, namespace, components, tmpDir)
|
||||
err = genInstallManifests(installVersion, namespace, installComponents, installRegistry, installImagePullSecret, tmpDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("install failed: %w", err)
|
||||
}
|
||||
@@ -101,6 +121,13 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
||||
} else {
|
||||
if verbose {
|
||||
fmt.Print(yaml)
|
||||
} else if installExport {
|
||||
fmt.Println("---")
|
||||
fmt.Println("# GitOps Toolkit revision", installVersion, time.Now().Format(time.RFC3339))
|
||||
fmt.Println("# Components:", strings.Join(installComponents, ","))
|
||||
fmt.Print(yaml)
|
||||
fmt.Println("---")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
logger.Successf("manifests build completed")
|
||||
@@ -128,7 +155,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
logger.Waitingf("verifying installation")
|
||||
for _, deployment := range components {
|
||||
for _, deployment := range installComponents {
|
||||
command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
||||
namespace, deployment, timeout.String())
|
||||
if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
|
||||
@@ -163,18 +190,49 @@ fieldSpecs:
|
||||
`
|
||||
|
||||
var kustomizationTmpl = `---
|
||||
{{- $version := .Version }}
|
||||
{{- $eventsAddr := .EventsAddr }}
|
||||
{{- $registry := .Registry }}
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: {{.Namespace}}
|
||||
|
||||
transformers:
|
||||
- labels.yaml
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- policies.yaml
|
||||
- roles
|
||||
- github.com/fluxcd/toolkit/manifests/policies?ref={{$version}}
|
||||
{{- range .Components }}
|
||||
- github.com/fluxcd/toolkit/manifests/bases/{{.}}?ref={{$version}}
|
||||
- {{.}}.yaml
|
||||
{{- end }}
|
||||
|
||||
patches:
|
||||
- path: node-selector.yaml
|
||||
target:
|
||||
kind: Deployment
|
||||
|
||||
patchesJson6902:
|
||||
{{- range $i, $component := .Components }}
|
||||
{{- if ne $component "notification-controller" }}
|
||||
- target:
|
||||
group: apps
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: {{$component}}
|
||||
patch: |-
|
||||
- op: replace
|
||||
path: /spec/template/spec/containers/0/args/0
|
||||
value: --events-addr={{$eventsAddr}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if $registry }}
|
||||
images:
|
||||
{{- range $i, $component := .Components }}
|
||||
- name: fluxcd/{{$component}}
|
||||
newName: {{$registry}}/{{$component}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
`
|
||||
|
||||
@@ -182,19 +240,85 @@ var kustomizationRolesTmpl = `---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- github.com/fluxcd/toolkit/manifests/rbac?ref={{.Version}}
|
||||
- rbac.yaml
|
||||
nameSuffix: -{{.Namespace}}
|
||||
`
|
||||
|
||||
func genInstallManifests(version string, namespace string, components []string, tmpDir string) error {
|
||||
var nodeSelectorTmpl = `---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: all
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
nodeSelector:
|
||||
kubernetes.io/arch: amd64
|
||||
kubernetes.io/os: linux
|
||||
{{- if .ImagePullSecret }}
|
||||
imagePullSecrets:
|
||||
- name: {{.ImagePullSecret}}
|
||||
{{- end }}
|
||||
`
|
||||
|
||||
func downloadManifests(version string, tmpDir string) error {
|
||||
ghURL := "https://github.com/fluxcd/toolkit/releases/latest/download/manifests.tar.gz"
|
||||
if strings.HasPrefix(version, "v") {
|
||||
ghURL = fmt.Sprintf("https://github.com/fluxcd/toolkit/releases/download/%s/manifests.tar.gz", version)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
req, err := http.NewRequest("GET", ghURL, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create HTTP request for %s, error: %w", ghURL, err)
|
||||
}
|
||||
|
||||
// download
|
||||
resp, err := http.DefaultClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download artifact from %s, error: %w", ghURL, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// check response
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("faild to download artifact from %s, status: %s", ghURL, resp.Status)
|
||||
}
|
||||
|
||||
// extract
|
||||
if _, err = untar.Untar(resp.Body, tmpDir); err != nil {
|
||||
return fmt.Errorf("faild to untar manifests from %s, error: %w", ghURL, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func genInstallManifests(version string, namespace string, components []string, registry, imagePullSecret, tmpDir string) error {
|
||||
eventsAddr := ""
|
||||
if utils.containsItemString(components, defaultNotification) {
|
||||
eventsAddr = fmt.Sprintf("http://%s/", defaultNotification)
|
||||
}
|
||||
|
||||
model := struct {
|
||||
Version string
|
||||
Namespace string
|
||||
Components []string
|
||||
Version string
|
||||
Namespace string
|
||||
Components []string
|
||||
EventsAddr string
|
||||
Registry string
|
||||
ImagePullSecret string
|
||||
}{
|
||||
Version: version,
|
||||
Namespace: namespace,
|
||||
Components: components,
|
||||
Version: version,
|
||||
Namespace: namespace,
|
||||
Components: components,
|
||||
EventsAddr: eventsAddr,
|
||||
Registry: registry,
|
||||
ImagePullSecret: imagePullSecret,
|
||||
}
|
||||
|
||||
if err := downloadManifests(version, tmpDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := utils.execTemplate(model, namespaceTmpl, path.Join(tmpDir, "namespace.yaml")); err != nil {
|
||||
@@ -205,6 +329,10 @@ func genInstallManifests(version string, namespace string, components []string,
|
||||
return fmt.Errorf("generate labels failed: %w", err)
|
||||
}
|
||||
|
||||
if err := utils.execTemplate(model, nodeSelectorTmpl, path.Join(tmpDir, "node-selector.yaml")); err != nil {
|
||||
return fmt.Errorf("generate node selector failed: %w", err)
|
||||
}
|
||||
|
||||
if err := utils.execTemplate(model, kustomizationTmpl, path.Join(tmpDir, "kustomization.yaml")); err != nil {
|
||||
return fmt.Errorf("generate kustomization failed: %w", err)
|
||||
}
|
||||
@@ -217,6 +345,10 @@ func genInstallManifests(version string, namespace string, components []string,
|
||||
return fmt.Errorf("generate roles failed: %w", err)
|
||||
}
|
||||
|
||||
if err := utils.copyFile(filepath.Join(tmpDir, "rbac.yaml"), filepath.Join(tmpDir, "roles/rbac.yaml")); err != nil {
|
||||
return fmt.Errorf("generate rbac failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ var rootCmd = &cobra.Command{
|
||||
SilenceErrors: true,
|
||||
Short: "Command line utility for assembling Kubernetes CD pipelines",
|
||||
Long: `Command line utility for assembling Kubernetes CD pipelines the GitOps way.`,
|
||||
Example: ` # Check prerequisites
|
||||
Example: ` # Check prerequisites
|
||||
tk check --pre
|
||||
|
||||
# Install the latest version of the toolkit
|
||||
@@ -53,8 +53,8 @@ var rootCmd = &cobra.Command{
|
||||
# List GitRepository sources and their status
|
||||
tk get sources git
|
||||
|
||||
# Trigger a GitRepository source sync
|
||||
tk sync source git webapp-latest
|
||||
# Trigger a GitRepository source reconciliation
|
||||
tk reconcile source git gitops-system
|
||||
|
||||
# Export GitRepository sources in YAML format
|
||||
tk export source git --all > sources.yaml
|
||||
@@ -65,13 +65,13 @@ var rootCmd = &cobra.Command{
|
||||
--path="./deploy/webapp/" \
|
||||
--prune=true \
|
||||
--interval=5m \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--health-check="Deployment/backend.webapp" \
|
||||
--health-check="Deployment/frontend.webapp" \
|
||||
--health-check-timeout=2m
|
||||
|
||||
# Trigger a git sync of the Kustomization's source and apply changes
|
||||
tk sync kustomization webapp-dev --with-source
|
||||
tk reconcile kustomization webapp-dev --with-source
|
||||
|
||||
# Suspend a Kustomization reconciliation
|
||||
tk suspend kustomization webapp-dev
|
||||
@@ -98,22 +98,25 @@ var (
|
||||
namespace string
|
||||
timeout time.Duration
|
||||
verbose bool
|
||||
components []string
|
||||
utils Utils
|
||||
pollInterval = 2 * time.Second
|
||||
logger tklog.Logger = printLogger{}
|
||||
)
|
||||
|
||||
var (
|
||||
defaultComponents = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
|
||||
defaultVersion = "latest"
|
||||
defaultNamespace = "gitops-system"
|
||||
defaultNotification = "notification-controller"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&namespace, "namespace", "", "gitops-system",
|
||||
rootCmd.PersistentFlags().StringVar(&namespace, "namespace", defaultNamespace,
|
||||
"the namespace scope for this operation")
|
||||
rootCmd.PersistentFlags().DurationVarP(&timeout, "timeout", "", 5*time.Minute,
|
||||
"timeout for this operation")
|
||||
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false,
|
||||
"print generated objects")
|
||||
rootCmd.PersistentFlags().StringSliceVar(&components, "components",
|
||||
[]string{"source-controller", "kustomize-controller", "notification-controller"},
|
||||
"list of components, accepts comma-separated values")
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -20,12 +20,12 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var syncCmd = &cobra.Command{
|
||||
Use: "sync",
|
||||
Short: "Synchronize sources and resources",
|
||||
Long: "The sync sub-commands trigger a reconciliation of sources and resources.",
|
||||
var reconcileCmd = &cobra.Command{
|
||||
Use: "reconcile",
|
||||
Short: "Reconcile sources and resources",
|
||||
Long: "The reconcile sub-commands trigger a reconciliation of sources and resources.",
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(syncCmd)
|
||||
rootCmd.AddCommand(reconcileCmd)
|
||||
}
|
||||
148
cmd/tk/reconcile_helmrelease.go
Normal file
148
cmd/tk/reconcile_helmrelease.go
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
)
|
||||
|
||||
var reconcileHrCmd = &cobra.Command{
|
||||
Use: "helmrelease [name]",
|
||||
Aliases: []string{"hr"},
|
||||
Short: "Reconcile a HelmRelease resource",
|
||||
Long: `
|
||||
The reconcile kustomization command triggers a reconciliation of a HelmRelease resource and waits for it to finish.`,
|
||||
Example: ` # Trigger a HelmRelease apply outside of the reconciliation interval
|
||||
tk reconcile hr podinfo
|
||||
|
||||
# Trigger a reconciliation of the HelmRelease's source and apply changes
|
||||
tk reconcile hr podinfo --with-source
|
||||
`,
|
||||
RunE: reconcileHrCmdRun,
|
||||
}
|
||||
|
||||
var (
|
||||
syncHrWithSource bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
reconcileHrCmd.Flags().BoolVar(&syncHrWithSource, "with-source", false, "reconcile HelmRelease source")
|
||||
|
||||
reconcileCmd.AddCommand(reconcileHrCmd)
|
||||
}
|
||||
|
||||
func reconcileHrCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("HelmRelease name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
var helmRelease helmv2.HelmRelease
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if syncHrWithSource {
|
||||
err := syncSourceHelmCmdRun(nil, []string{helmRelease.Spec.Chart.SourceRef.Name})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
logger.Actionf("annotating HelmRelease %s in %s namespace", name, namespace)
|
||||
if helmRelease.Annotations == nil {
|
||||
helmRelease.Annotations = map[string]string{
|
||||
helmv2.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
} else {
|
||||
helmRelease.Annotations[helmv2.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
|
||||
}
|
||||
if err := kubeClient.Update(ctx, &helmRelease); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRelease annotated")
|
||||
}
|
||||
|
||||
logger.Waitingf("waiting for HelmRelease reconciliation")
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isHelmReleaseReady(ctx, kubeClient, name, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("HelmRelease reconciliation completed")
|
||||
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if helmRelease.Status.LastAppliedRevision != "" {
|
||||
logger.Successf("reconciled revision %s", helmRelease.Status.LastAppliedRevision)
|
||||
} else {
|
||||
return fmt.Errorf("HelmRelease reconciliation failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isHelmReleaseReady(ctx context.Context, kubeClient client.Client, name, namespace string) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
var helmRelease helmv2.HelmRelease
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
err := kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, condition := range helmRelease.Status.Conditions {
|
||||
if condition.Type == helmv2.ReadyCondition {
|
||||
if condition.Status == corev1.ConditionTrue {
|
||||
return true, nil
|
||||
} else if condition.Status == corev1.ConditionFalse {
|
||||
return false, fmt.Errorf(condition.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
@@ -27,19 +27,19 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
var syncKsCmd = &cobra.Command{
|
||||
var reconcileKsCmd = &cobra.Command{
|
||||
Use: "kustomization [name]",
|
||||
Aliases: []string{"ks"},
|
||||
Short: "Synchronize a Kustomization resource",
|
||||
Short: "Reconcile a Kustomization resource",
|
||||
Long: `
|
||||
The sync kustomization command triggers a reconciliation of a Kustomization resource and waits for it to finish.`,
|
||||
The reconcile kustomization command triggers a reconciliation of a Kustomization resource and waits for it to finish.`,
|
||||
Example: ` # Trigger a Kustomization apply outside of the reconciliation interval
|
||||
sync kustomization podinfo
|
||||
tk reconcile kustomization podinfo
|
||||
|
||||
# Trigger a sync of the Kustomization's source and apply changes
|
||||
sync kustomization podinfo --with-source
|
||||
tk reconcile kustomization podinfo --with-source
|
||||
`,
|
||||
RunE: syncKsCmdRun,
|
||||
RunE: reconcileKsCmdRun,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -47,12 +47,12 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
syncKsCmd.Flags().BoolVar(&syncKsWithSource, "with-source", false, "synchronize kustomization source")
|
||||
reconcileKsCmd.Flags().BoolVar(&syncKsWithSource, "with-source", false, "reconcile kustomization source")
|
||||
|
||||
syncCmd.AddCommand(syncKsCmd)
|
||||
reconcileCmd.AddCommand(reconcileKsCmd)
|
||||
}
|
||||
|
||||
func syncKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
func reconcileKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("kustomization name is required")
|
||||
}
|
||||
@@ -86,10 +86,10 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
logger.Actionf("annotating kustomization %s in %s namespace", name, namespace)
|
||||
if kustomization.Annotations == nil {
|
||||
kustomization.Annotations = map[string]string{
|
||||
kustomizev1.SyncAtAnnotation: time.Now().String(),
|
||||
kustomizev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
} else {
|
||||
kustomization.Annotations[kustomizev1.SyncAtAnnotation] = time.Now().String()
|
||||
kustomization.Annotations[kustomizev1.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
|
||||
}
|
||||
if err := kubeClient.Update(ctx, &kustomization); err != nil {
|
||||
return err
|
||||
@@ -97,13 +97,13 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
logger.Successf("kustomization annotated")
|
||||
}
|
||||
|
||||
logger.Waitingf("waiting for kustomization sync")
|
||||
logger.Waitingf("waiting for kustomization reconciliation")
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isKustomizationReady(ctx, kubeClient, name, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("kustomization sync completed")
|
||||
logger.Successf("kustomization reconciliation completed")
|
||||
|
||||
err = kubeClient.Get(ctx, namespacedName, &kustomization)
|
||||
if err != nil {
|
||||
@@ -111,7 +111,7 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if kustomization.Status.LastAppliedRevision != "" {
|
||||
logger.Successf("applied revision %s", kustomization.Status.LastAppliedRevision)
|
||||
logger.Successf("reconciled revision %s", kustomization.Status.LastAppliedRevision)
|
||||
} else {
|
||||
return fmt.Errorf("kustomization sync failed")
|
||||
}
|
||||
@@ -20,12 +20,12 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var syncSourceCmd = &cobra.Command{
|
||||
var reconcileSourceCmd = &cobra.Command{
|
||||
Use: "source",
|
||||
Short: "Synchronize sources",
|
||||
Long: "The sync source sub-commands trigger a reconciliation of sources.",
|
||||
Short: "Reconcile sources",
|
||||
Long: "The reconcile source sub-commands trigger a reconciliation of sources.",
|
||||
}
|
||||
|
||||
func init() {
|
||||
syncCmd.AddCommand(syncSourceCmd)
|
||||
reconcileCmd.AddCommand(reconcileSourceCmd)
|
||||
}
|
||||
@@ -26,18 +26,18 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var syncSourceGitCmd = &cobra.Command{
|
||||
var reconcileSourceGitCmd = &cobra.Command{
|
||||
Use: "git [name]",
|
||||
Short: "Synchronize a GitRepository source",
|
||||
Long: `The sync source command triggers a reconciliation of a GitRepository resource and waits for it to finish.`,
|
||||
Short: "Reconcile a GitRepository source",
|
||||
Long: `The reconcile source command triggers a reconciliation of a GitRepository resource and waits for it to finish.`,
|
||||
Example: ` # Trigger a git pull for an existing source
|
||||
sync source git podinfo
|
||||
tk reconcile source git podinfo
|
||||
`,
|
||||
RunE: syncSourceGitCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
syncSourceCmd.AddCommand(syncSourceGitCmd)
|
||||
reconcileSourceCmd.AddCommand(reconcileSourceGitCmd)
|
||||
}
|
||||
|
||||
func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
@@ -68,23 +68,23 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if gitRepository.Annotations == nil {
|
||||
gitRepository.Annotations = map[string]string{
|
||||
sourcev1.SyncAtAnnotation: time.Now().String(),
|
||||
sourcev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
} else {
|
||||
gitRepository.Annotations[sourcev1.SyncAtAnnotation] = time.Now().String()
|
||||
gitRepository.Annotations[sourcev1.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
|
||||
}
|
||||
if err := kubeClient.Update(ctx, &gitRepository); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("source annotated")
|
||||
|
||||
logger.Waitingf("waiting for git sync")
|
||||
logger.Waitingf("waiting for reconciliation")
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("git sync completed")
|
||||
logger.Successf("git reconciliation completed")
|
||||
|
||||
err = kubeClient.Get(ctx, namespacedName, &gitRepository)
|
||||
if err != nil {
|
||||
@@ -94,7 +94,7 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if gitRepository.Status.Artifact != nil {
|
||||
logger.Successf("fetched revision %s", gitRepository.Status.Artifact.Revision)
|
||||
} else {
|
||||
return fmt.Errorf("git sync failed, artifact not found")
|
||||
return fmt.Errorf("git reconciliation failed, artifact not found")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
130
cmd/tk/reconcile_source_helm.go
Normal file
130
cmd/tk/reconcile_source_helm.go
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
)
|
||||
|
||||
var reconcileSourceHelmCmd = &cobra.Command{
|
||||
Use: "helm [name]",
|
||||
Short: "Reconcile a HelmRepository source",
|
||||
Long: `The reconcile source command triggers a reconciliation of a HelmRepository resource and waits for it to finish.`,
|
||||
Example: ` # Trigger a reconciliation for an existing source
|
||||
tk reconcile source helm podinfo
|
||||
`,
|
||||
RunE: syncSourceHelmCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
reconcileSourceCmd.AddCommand(reconcileSourceHelmCmd)
|
||||
}
|
||||
|
||||
func syncSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("source name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
logger.Actionf("annotating source %s in %s namespace", name, namespace)
|
||||
var helmRepository sourcev1.HelmRepository
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRepository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if helmRepository.Annotations == nil {
|
||||
helmRepository.Annotations = map[string]string{
|
||||
sourcev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
} else {
|
||||
helmRepository.Annotations[sourcev1.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
|
||||
}
|
||||
if err := kubeClient.Update(ctx, &helmRepository); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("source annotated")
|
||||
|
||||
logger.Waitingf("waiting for reconciliation")
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isHelmRepositoryReady(ctx, kubeClient, name, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("helm reconciliation completed")
|
||||
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRepository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if helmRepository.Status.Artifact != nil {
|
||||
logger.Successf("fetched revision %s", helmRepository.Status.Artifact.Revision)
|
||||
} else {
|
||||
return fmt.Errorf("helm reconciliation failed, artifact not found")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isHelmRepositoryReady(ctx context.Context, kubeClient client.Client, name, namespace string) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
var helmRepository sourcev1.HelmRepository
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
err := kubeClient.Get(ctx, namespacedName, &helmRepository)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, condition := range helmRepository.Status.Conditions {
|
||||
if condition.Type == sourcev1.ReadyCondition {
|
||||
if condition.Status == corev1.ConditionTrue {
|
||||
return true, nil
|
||||
} else if condition.Status == corev1.ConditionFalse {
|
||||
return false, fmt.Errorf(condition.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
129
cmd/tk/resume_helmrelease.go
Normal file
129
cmd/tk/resume_helmrelease.go
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
)
|
||||
|
||||
var resumeHrCmd = &cobra.Command{
|
||||
Use: "helmrelease [name]",
|
||||
Aliases: []string{"hr"},
|
||||
Short: "Resume a suspended HelmRelease",
|
||||
Long: `The resume command marks a previously suspended HelmRelease resource for reconciliation and waits for it to
|
||||
finish the apply.`,
|
||||
Example: ` # Resume reconciliation for an existing Helm release
|
||||
tk resume hr podinfo
|
||||
`,
|
||||
RunE: resumeHrCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
resumeCmd.AddCommand(resumeHrCmd)
|
||||
}
|
||||
|
||||
func resumeHrCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("HelmRelease name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
var helmRelease helmv2.HelmRelease
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("resuming HelmRelease %s in %s namespace", name, namespace)
|
||||
helmRelease.Spec.Suspend = false
|
||||
if err := kubeClient.Update(ctx, &helmRelease); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRelease resumed")
|
||||
|
||||
logger.Waitingf("waiting for HelmRelease reconciliation")
|
||||
if err := wait.PollImmediate(pollInterval, timeout,
|
||||
isHelmReleaseResumed(ctx, kubeClient, name, namespace)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Successf("HelmRelease reconciliation completed")
|
||||
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if helmRelease.Status.LastAppliedRevision != "" {
|
||||
logger.Successf("applied revision %s", helmRelease.Status.LastAppliedRevision)
|
||||
} else {
|
||||
return fmt.Errorf("HelmRelease reconciliation failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isHelmReleaseResumed(ctx context.Context, kubeClient client.Client, name, namespace string) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
var helmRelease helmv2.HelmRelease
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
err := kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, condition := range helmRelease.Status.Conditions {
|
||||
if condition.Type == helmv2.ReadyCondition {
|
||||
if condition.Status == corev1.ConditionTrue {
|
||||
return true, nil
|
||||
} else if condition.Status == corev1.ConditionFalse {
|
||||
if condition.Reason == helmv2.SuspendedReason {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf(condition.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,9 @@ var resumeKsCmd = &cobra.Command{
|
||||
Short: "Resume a suspended Kustomization",
|
||||
Long: `The resume command marks a previously suspended Kustomization resource for reconciliation and waits for it to
|
||||
finish the apply.`,
|
||||
Example: ` # Resume reconciliation for an existing Kustomization
|
||||
tk resume ks podinfo
|
||||
`,
|
||||
RunE: resumeKsCmdRun,
|
||||
}
|
||||
|
||||
|
||||
76
cmd/tk/suspend_helmrelease.go
Normal file
76
cmd/tk/suspend_helmrelease.go
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2020 The Flux CD contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
)
|
||||
|
||||
var suspendHrCmd = &cobra.Command{
|
||||
Use: "helmrelease [name]",
|
||||
Aliases: []string{"hr"},
|
||||
Short: "Suspend reconciliation of HelmRelease",
|
||||
Long: "The suspend command disables the reconciliation of a HelmRelease resource.",
|
||||
Example: ` # Suspend reconciliation for an existing Helm release
|
||||
tk suspend hr podinfo
|
||||
`,
|
||||
RunE: suspendHrCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
suspendCmd.AddCommand(suspendHrCmd)
|
||||
}
|
||||
|
||||
func suspendHrCmdRun(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("HelmRelease name is required")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
kubeClient, err := utils.kubeClient(kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespacedName := types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
var helmRelease helmv2.HelmRelease
|
||||
err = kubeClient.Get(ctx, namespacedName, &helmRelease)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Actionf("suspending HelmRelease %s in %s namespace", name, namespace)
|
||||
helmRelease.Spec.Suspend = true
|
||||
if err := kubeClient.Update(ctx, &helmRelease); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Successf("HelmRelease suspended")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -29,7 +29,10 @@ var suspendKsCmd = &cobra.Command{
|
||||
Aliases: []string{"ks"},
|
||||
Short: "Suspend reconciliation of Kustomization",
|
||||
Long: "The suspend command disables the reconciliation of a Kustomization resource.",
|
||||
RunE: suspendKsCmdRun,
|
||||
Example: ` # Suspend reconciliation for an existing Kustomization
|
||||
tk suspend ks podinfo
|
||||
`,
|
||||
RunE: suspendKsCmdRun,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -19,10 +19,12 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/manifoldco/promptui"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
)
|
||||
|
||||
var uninstallCmd = &cobra.Command{
|
||||
@@ -30,27 +32,27 @@ var uninstallCmd = &cobra.Command{
|
||||
Short: "Uninstall the toolkit components",
|
||||
Long: "The uninstall command removes the namespace, cluster roles, cluster role bindings and CRDs from the cluster.",
|
||||
Example: ` # Dry-run uninstall of all components
|
||||
uninstall --dry-run --namespace=gitops-system
|
||||
tk uninstall --dry-run --namespace=gitops-system
|
||||
|
||||
# Uninstall all components and delete custom resource definitions
|
||||
uninstall --crds --namespace=gitops-system
|
||||
tk uninstall --resources --crds --namespace=gitops-system
|
||||
`,
|
||||
RunE: uninstallCmdRun,
|
||||
}
|
||||
|
||||
var (
|
||||
uninstallCRDs bool
|
||||
uninstallKustomizations bool
|
||||
uninstallDryRun bool
|
||||
uninstallSilent bool
|
||||
uninstallCRDs bool
|
||||
uninstallResources bool
|
||||
uninstallDryRun bool
|
||||
uninstallSilent bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
uninstallCmd.Flags().BoolVarP(&uninstallKustomizations, "kustomizations", "", false,
|
||||
"removes all Kustomizations previously installed")
|
||||
uninstallCmd.Flags().BoolVarP(&uninstallCRDs, "crds", "", false,
|
||||
uninstallCmd.Flags().BoolVar(&uninstallResources, "resources", false,
|
||||
"removes custom resources such as Kustomizations, GitRepositories and HelmRepositories")
|
||||
uninstallCmd.Flags().BoolVar(&uninstallCRDs, "crds", false,
|
||||
"removes all CRDs previously installed")
|
||||
uninstallCmd.Flags().BoolVarP(&uninstallDryRun, "dry-run", "", false,
|
||||
uninstallCmd.Flags().BoolVar(&uninstallDryRun, "dry-run", false,
|
||||
"only print the object that would be deleted")
|
||||
uninstallCmd.Flags().BoolVarP(&uninstallSilent, "silent", "s", false,
|
||||
"delete components without asking for confirmation")
|
||||
@@ -75,18 +77,19 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if uninstallKustomizations {
|
||||
logger.Actionf("uninstalling kustomizations")
|
||||
command := fmt.Sprintf("kubectl -n %s delete kustomizations --all --timeout=%s %s",
|
||||
namespace, timeout.String(), dryRun)
|
||||
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
|
||||
return fmt.Errorf("uninstall failed")
|
||||
if uninstallResources {
|
||||
logger.Actionf("uninstalling custom resources")
|
||||
for _, kind := range []string{
|
||||
kustomizev1.KustomizationKind,
|
||||
sourcev1.GitRepositoryKind,
|
||||
sourcev1.HelmRepositoryKind,
|
||||
} {
|
||||
command := fmt.Sprintf("kubectl -n %s delete %s --all --timeout=%s %s",
|
||||
namespace, kind, timeout.String(), dryRun)
|
||||
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
|
||||
return fmt.Errorf("uninstall failed")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use the kustomizations snapshots to create a list of objects
|
||||
// that are subject to deletion and wait for all of them to be terminated
|
||||
logger.Waitingf("waiting on GC")
|
||||
time.Sleep(30 * time.Second)
|
||||
}
|
||||
|
||||
kinds := "namespace,clusterroles,clusterrolebindings"
|
||||
|
||||
@@ -26,12 +26,14 @@ import (
|
||||
"os/exec"
|
||||
"text/template"
|
||||
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
)
|
||||
|
||||
type Utils struct {
|
||||
@@ -118,6 +120,7 @@ func (*Utils) kubeClient(config string) (client.Client, error) {
|
||||
_ = corev1.AddToScheme(scheme)
|
||||
_ = sourcev1.AddToScheme(scheme)
|
||||
_ = kustomizev1.AddToScheme(scheme)
|
||||
_ = helmv2.AddToScheme(scheme)
|
||||
|
||||
kubeClient, err := client.New(cfg, client.Options{
|
||||
Scheme: scheme,
|
||||
@@ -143,3 +146,32 @@ func (*Utils) writeFile(content, filename string) error {
|
||||
|
||||
return file.Sync()
|
||||
}
|
||||
|
||||
func (*Utils) copyFile(src, dst string) error {
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
out, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return out.Close()
|
||||
}
|
||||
|
||||
func (*Utils) containsItemString(s []string, e string) bool {
|
||||
for _, a := range s {
|
||||
if a == e {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
BIN
docs/_files/cp-dashboard-p1.png
Normal file
BIN
docs/_files/cp-dashboard-p1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
BIN
docs/_files/cp-dashboard-p2.png
Normal file
BIN
docs/_files/cp-dashboard-p2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 146 KiB |
BIN
docs/_files/helm-controller.png
Normal file
BIN
docs/_files/helm-controller.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
BIN
docs/_files/notification-controller.png
Normal file
BIN
docs/_files/notification-controller.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
73
docs/_static/custom.css
vendored
73
docs/_static/custom.css
vendored
@@ -22,3 +22,76 @@ body {
|
||||
.md-header-nav__title {
|
||||
font-size: .85rem;
|
||||
}
|
||||
|
||||
.check-bullet {
|
||||
color:#07bfa5;
|
||||
background-color: white;
|
||||
margin-left:-22px;
|
||||
}
|
||||
|
||||
/* Progress bar styling */
|
||||
|
||||
.progress-label {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
width: 100%;
|
||||
/* remove original styling for thin styling
|
||||
margin: 0 ! important; */
|
||||
margin-top: -0.4rem ! important;
|
||||
line-height: 1.2rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
/*remove original styling for thin styling
|
||||
height: 1.2rem; */
|
||||
height: 0.4rem;
|
||||
float: left;
|
||||
background: repeating-linear-gradient(
|
||||
45deg,
|
||||
rgba(255, 255, 255, 0.2),
|
||||
rgba(255, 255, 255, 0.2) 10px,
|
||||
rgba(255, 255, 255, 0.3) 10px,
|
||||
rgba(255, 255, 255, 0.3) 20px
|
||||
) #2979ff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.progress {
|
||||
display: block;
|
||||
width: 100%;
|
||||
/* remove original styling for thin styling
|
||||
margin: 0.5rem 0;
|
||||
height: 1.2rem; */
|
||||
margin-top: 0.9rem;
|
||||
height: 0.4rem;
|
||||
background-color: #eeeeee;
|
||||
position: relative;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.progress-100plus .progress-bar {
|
||||
background-color: #00c853;
|
||||
}
|
||||
|
||||
.progress-80plus .progress-bar {
|
||||
background-color: #64dd17;
|
||||
}
|
||||
|
||||
.progress-60plus .progress-bar {
|
||||
background-color: #fbc02d;
|
||||
}
|
||||
|
||||
.progress-40plus .progress-bar {
|
||||
background-color: #ff9100;
|
||||
}
|
||||
|
||||
.progress-20plus .progress-bar {
|
||||
background-color: #ff5252;
|
||||
}
|
||||
|
||||
.progress-0plus .progress-bar {
|
||||
background-color: #ff1744;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Check prerequisites
|
||||
# Check prerequisites
|
||||
tk check --pre
|
||||
|
||||
# Install the latest version of the toolkit
|
||||
@@ -24,8 +24,8 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
|
||||
# List GitRepository sources and their status
|
||||
tk get sources git
|
||||
|
||||
# Trigger a GitRepository source sync
|
||||
tk sync source git webapp-latest
|
||||
# Trigger a GitRepository source reconciliation
|
||||
tk reconcile source git gitops-system
|
||||
|
||||
# Export GitRepository sources in YAML format
|
||||
tk export source git --all > sources.yaml
|
||||
@@ -36,13 +36,13 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
|
||||
--path="./deploy/webapp/" \
|
||||
--prune=true \
|
||||
--interval=5m \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--health-check="Deployment/backend.webapp" \
|
||||
--health-check="Deployment/frontend.webapp" \
|
||||
--health-check-timeout=2m
|
||||
|
||||
# Trigger a git sync of the Kustomization's source and apply changes
|
||||
tk sync kustomization webapp-dev --with-source
|
||||
tk reconcile kustomization webapp-dev --with-source
|
||||
|
||||
# Suspend a Kustomization reconciliation
|
||||
tk suspend kustomization webapp-dev
|
||||
@@ -67,12 +67,11 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
|
||||
### Options
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
-h, --help help for tk
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
-h, --help help for tk
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
@@ -85,8 +84,8 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
|
||||
* [tk export](tk_export.md) - Export resources in YAML format
|
||||
* [tk get](tk_get.md) - Get sources and resources
|
||||
* [tk install](tk_install.md) - Install the toolkit components
|
||||
* [tk reconcile](tk_reconcile.md) - Reconcile sources and resources
|
||||
* [tk resume](tk_resume.md) - Resume suspended resources
|
||||
* [tk suspend](tk_suspend.md) - Suspend resources
|
||||
* [tk sync](tk_sync.md) - Synchronize sources and resources
|
||||
* [tk uninstall](tk_uninstall.md) - Uninstall the toolkit components
|
||||
|
||||
|
||||
@@ -9,18 +9,20 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for bootstrap
|
||||
--version string toolkit tag or branch (default "master")
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
|
||||
-h, --help help for bootstrap
|
||||
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
|
||||
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
|
||||
-v, --version string toolkit version (default "latest")
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -21,19 +21,19 @@ tk bootstrap github [flags]
|
||||
export GITHUB_TOKEN=<my-token>
|
||||
|
||||
# Run bootstrap for a private repo owned by a GitHub organization
|
||||
bootstrap github --owner=<organization> --repository=<repo name>
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name>
|
||||
|
||||
# Run bootstrap for a private repo and assign organization teams to it
|
||||
bootstrap github --owner=<organization> --repository=<repo name> --team=<team1 slug> --team=<team2 slug>
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name> --team=<team1 slug> --team=<team2 slug>
|
||||
|
||||
# Run bootstrap for a repository path
|
||||
bootstrap github --owner=<organization> --repository=<repo name> --path=dev-cluster
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name> --path=dev-cluster
|
||||
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
tk bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise
|
||||
bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
|
||||
tk bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
|
||||
|
||||
```
|
||||
|
||||
@@ -54,12 +54,14 @@ tk bootstrap github [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--version string toolkit tag or branch (default "master")
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
|
||||
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
-v, --version string toolkit version (default "latest")
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -21,16 +21,16 @@ tk bootstrap gitlab [flags]
|
||||
export GITLAB_TOKEN=<my-token>
|
||||
|
||||
# Run bootstrap for a private repo owned by a GitLab group
|
||||
bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
tk bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
|
||||
# Run bootstrap for a repository path
|
||||
bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster
|
||||
tk bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster
|
||||
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
tk bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
|
||||
# Run bootstrap for a private repo hosted on a GitLab server
|
||||
bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
|
||||
tk bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
|
||||
|
||||
```
|
||||
|
||||
@@ -50,12 +50,14 @@ tk bootstrap gitlab [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--version string toolkit tag or branch (default "master")
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
|
||||
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
-v, --version string toolkit version (default "latest")
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -15,28 +15,28 @@ tk check [flags]
|
||||
|
||||
```
|
||||
# Run pre-installation checks
|
||||
check --pre
|
||||
tk check --pre
|
||||
|
||||
# Run installation checks
|
||||
check
|
||||
tk check
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for check
|
||||
--pre only run pre-installation checks
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
|
||||
-h, --help help for check
|
||||
--pre only run pre-installation checks
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -33,11 +33,10 @@ To configure your bash shell to load completions for each session add to your ba
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -17,16 +17,16 @@ The create sub-commands generate sources and resources.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk create helmrelease](tk_create_helmrelease.md) - Create or update a HelmRelease resource
|
||||
* [tk create kustomization](tk_create_kustomization.md) - Create or update a Kustomization resource
|
||||
* [tk create source](tk_create_source.md) - Create or update sources
|
||||
|
||||
|
||||
71
docs/cmd/tk_create_helmrelease.md
Normal file
71
docs/cmd/tk_create_helmrelease.md
Normal file
@@ -0,0 +1,71 @@
|
||||
## tk create helmrelease
|
||||
|
||||
Create or update a HelmRelease resource
|
||||
|
||||
### Synopsis
|
||||
|
||||
The helmrelease create command generates a HelmRelease resource for a given HelmRepository source.
|
||||
|
||||
```
|
||||
tk create helmrelease [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Create a HelmRelease from a source
|
||||
tk create hr podinfo \
|
||||
--interval=10m \
|
||||
--release-name=podinfo \
|
||||
--target-namespace=default \
|
||||
--source=podinfo \
|
||||
--chart-name=podinfo \
|
||||
--chart-version=">4.0.0"
|
||||
|
||||
# Create a HelmRelease with values for a local YAML file
|
||||
tk create hr podinfo \
|
||||
--target-namespace=default \
|
||||
--source=podinfo \
|
||||
--chart-name=podinfo \
|
||||
--chart-version=4.0.5 \
|
||||
--values=./my-values.yaml
|
||||
|
||||
# Create a HelmRelease definition on disk without applying it on the cluster
|
||||
tk create hr podinfo \
|
||||
--target-namespace=default \
|
||||
--source=podinfo \
|
||||
--chart-name=podinfo \
|
||||
--chart-version=4.0.5 \
|
||||
--values=./values.yaml \
|
||||
--export > podinfo-release.yaml
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--chart-name string Helm chart name
|
||||
--chart-version string Helm chart version, accepts semver range
|
||||
--depends-on stringArray HelmReleases that must be ready before this release can be installed
|
||||
-h, --help help for helmrelease
|
||||
--release-name string name used for the Helm release, defaults to a composition of '<target-namespace>-<hr-name>'
|
||||
--source string HelmRepository name
|
||||
--target-namespace string namespace to install this release, defaults to the HelmRelease namespace
|
||||
--values string local path to the values.yaml file
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk create](tk_create.md) - Create or update sources and resources
|
||||
|
||||
@@ -14,32 +14,32 @@ tk create kustomization [name] [flags]
|
||||
|
||||
```
|
||||
# Create a Kustomization resource from a source at a given path
|
||||
create kustomization contour \
|
||||
tk create kustomization contour \
|
||||
--source=contour \
|
||||
--path="./examples/contour/" \
|
||||
--prune=true \
|
||||
--interval=10m \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--health-check="Deployment/contour.projectcontour" \
|
||||
--health-check="DaemonSet/envoy.projectcontour" \
|
||||
--health-check-timeout=3m
|
||||
|
||||
# Create a Kustomization resource that depends on the previous one
|
||||
create kustomization webapp \
|
||||
tk create kustomization webapp \
|
||||
--depends-on=contour \
|
||||
--source=webapp \
|
||||
--path="./deploy/overlays/dev" \
|
||||
--prune=true \
|
||||
--interval=5m \
|
||||
--validate=client
|
||||
--validation=client
|
||||
|
||||
# Create a Kustomization resource that runs under a service account
|
||||
create kustomization webapp \
|
||||
tk create kustomization webapp \
|
||||
--source=webapp \
|
||||
--path="./deploy/overlays/staging" \
|
||||
--prune=true \
|
||||
--interval=5m \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--sa-name=reconclier \
|
||||
--sa-namespace=staging
|
||||
|
||||
@@ -57,19 +57,18 @@ tk create kustomization [name] [flags]
|
||||
--sa-name string service account name
|
||||
--sa-namespace string service account namespace
|
||||
--source string GitRepository name
|
||||
--validate string validate the manifests before applying them on the cluster, can be 'client' or 'server'
|
||||
--validation string validate the manifests before applying them on the cluster, can be 'client' or 'server'
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -15,17 +15,17 @@ The create source sub-commands generate sources.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk create](tk_create.md) - Create or update sources and resources
|
||||
* [tk create source git](tk_create_source_git.md) - Create or update a GitRepository source
|
||||
* [tk create source helm](tk_create_source_helm.md) - Create or update a HelmRepository source
|
||||
|
||||
|
||||
@@ -17,35 +17,35 @@ tk create source git [name] [flags]
|
||||
|
||||
```
|
||||
# Create a source from a public Git repository master branch
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--branch=master
|
||||
|
||||
# Create a source from a Git repository pinned to specific git tag
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--tag="3.2.3"
|
||||
|
||||
# Create a source from a public Git repository tag that matches a semver range
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--tag-semver=">=3.2.0 <3.3.0"
|
||||
|
||||
# Create a source from a Git repository using SSH authentication
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=ssh://git@github.com/stefanprodan/podinfo \
|
||||
--branch=master
|
||||
|
||||
# Create a source from a Git repository using SSH authentication and an
|
||||
# ECDSA P-521 curve public key
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=ssh://git@github.com/stefanprodan/podinfo \
|
||||
--branch=master \
|
||||
--ssh-key-algorithm=ecdsa \
|
||||
--ssh-ecdsa-curve=p521
|
||||
|
||||
# Create a source from a Git repository using basic authentication
|
||||
create source git podinfo \
|
||||
tk create source git podinfo \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--username=username \
|
||||
--password=password
|
||||
@@ -70,13 +70,12 @@ tk create source git [name] [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
64
docs/cmd/tk_create_source_helm.md
Normal file
64
docs/cmd/tk_create_source_helm.md
Normal file
@@ -0,0 +1,64 @@
|
||||
## tk create source helm
|
||||
|
||||
Create or update a HelmRepository source
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
The create source helm command generates a HelmRepository resource and waits for it to fetch the index.
|
||||
For private Helm repositories, the basic authentication credentials are stored in a Kubernetes secret.
|
||||
|
||||
```
|
||||
tk create source helm [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Create a source from a public Helm repository
|
||||
tk create source helm podinfo \
|
||||
--url=https://stefanprodan.github.io/podinfo \
|
||||
--interval=10m
|
||||
|
||||
# Create a source from a Helm repository using basic authentication
|
||||
tk create source helm podinfo \
|
||||
--url=https://stefanprodan.github.io/podinfo \
|
||||
--username=username \
|
||||
--password=password
|
||||
|
||||
# Create a source from a Helm repository using TLS authentication
|
||||
tk create source helm podinfo \
|
||||
--url=https://stefanprodan.github.io/podinfo \
|
||||
--cert-file=./cert.crt \
|
||||
--key-file=./key.crt \
|
||||
--ca-file=./ca.crt
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--ca-file string TLS authentication CA file path
|
||||
--cert-file string TLS authentication cert file path
|
||||
-h, --help help for helm
|
||||
--key-file string TLS authentication key file path
|
||||
-p, --password string basic authentication password
|
||||
--url string Helm repository address
|
||||
-u, --username string basic authentication username
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--export export in YAML format to stdout
|
||||
--interval duration source sync interval (default 1m0s)
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk create source](tk_create_source.md) - Create or update sources
|
||||
|
||||
@@ -16,16 +16,16 @@ The delete sub-commands delete sources and resources.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk delete helmrelease](tk_delete_helmrelease.md) - Delete a HelmRelease resource
|
||||
* [tk delete kustomization](tk_delete_kustomization.md) - Delete a Kustomization resource
|
||||
* [tk delete source](tk_delete_source.md) - Delete sources
|
||||
|
||||
|
||||
40
docs/cmd/tk_delete_helmrelease.md
Normal file
40
docs/cmd/tk_delete_helmrelease.md
Normal file
@@ -0,0 +1,40 @@
|
||||
## tk delete helmrelease
|
||||
|
||||
Delete a HelmRelease resource
|
||||
|
||||
### Synopsis
|
||||
|
||||
The delete helmrelease command removes the given HelmRelease from the cluster.
|
||||
|
||||
```
|
||||
tk delete helmrelease [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Delete a Helm release and the Kubernetes resources created by it
|
||||
tk delete hr podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helmrelease
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk delete](tk_delete.md) - Delete sources and resources
|
||||
|
||||
@@ -10,6 +10,14 @@ The delete kustomization command deletes the given Kustomization from the cluste
|
||||
tk delete kustomization [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Delete a kustomization and the Kubernetes resources created by it
|
||||
tk delete kustomization podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
@@ -19,12 +27,11 @@ tk delete kustomization [name] [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -15,16 +15,16 @@ The delete source sub-commands delete sources.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk delete](tk_delete.md) - Delete sources and resources
|
||||
* [tk delete source git](tk_delete_source_git.md) - Delete a GitRepository source
|
||||
* [tk delete source helm](tk_delete_source_helm.md) - Delete a HelmRepository source
|
||||
|
||||
|
||||
@@ -10,6 +10,14 @@ The delete source git command deletes the given GitRepository from the cluster.
|
||||
tk delete source git [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Delete a Git repository
|
||||
tk delete source git podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
@@ -19,12 +27,11 @@ tk delete source git [name] [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
40
docs/cmd/tk_delete_source_helm.md
Normal file
40
docs/cmd/tk_delete_source_helm.md
Normal file
@@ -0,0 +1,40 @@
|
||||
## tk delete source helm
|
||||
|
||||
Delete a HelmRepository source
|
||||
|
||||
### Synopsis
|
||||
|
||||
The delete source helm command deletes the given HelmRepository from the cluster.
|
||||
|
||||
```
|
||||
tk delete source helm [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Delete a Helm repository
|
||||
tk delete source helm podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helm
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
-s, --silent delete resource without asking for confirmation
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk delete source](tk_delete_source.md) - Delete sources
|
||||
|
||||
@@ -16,16 +16,16 @@ The export sub-commands export resources in YAML format.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk export helmrelease](tk_export_helmrelease.md) - Export HelmRelease resources in YAML format
|
||||
* [tk export kustomization](tk_export_kustomization.md) - Export Kustomization resources in YAML format
|
||||
* [tk export source](tk_export_source.md) - Export sources
|
||||
|
||||
|
||||
43
docs/cmd/tk_export_helmrelease.md
Normal file
43
docs/cmd/tk_export_helmrelease.md
Normal file
@@ -0,0 +1,43 @@
|
||||
## tk export helmrelease
|
||||
|
||||
Export HelmRelease resources in YAML format
|
||||
|
||||
### Synopsis
|
||||
|
||||
The export helmrelease command exports one or all HelmRelease resources in YAML format.
|
||||
|
||||
```
|
||||
tk export helmrelease [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Export all HelmRelease resources
|
||||
tk export helmrelease --all > kustomizations.yaml
|
||||
|
||||
# Export a HelmRelease
|
||||
tk export hr my-app > app-release.yaml
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helmrelease
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--all select all resources
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk export](tk_export.md) - Export resources in YAML format
|
||||
|
||||
@@ -14,10 +14,10 @@ tk export kustomization [name] [flags]
|
||||
|
||||
```
|
||||
# Export all Kustomization resources
|
||||
export kustomization --all > kustomizations.yaml
|
||||
tk export kustomization --all > kustomizations.yaml
|
||||
|
||||
# Export a Kustomization
|
||||
export kustomization my-app > kustomization.yaml
|
||||
tk export kustomization my-app > kustomization.yaml
|
||||
|
||||
```
|
||||
|
||||
@@ -30,12 +30,11 @@ tk export kustomization [name] [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--all select all resources
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--all select all resources
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -16,16 +16,16 @@ The export source sub-commands export sources in YAML format.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--all select all resources
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--all select all resources
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk export](tk_export.md) - Export resources in YAML format
|
||||
* [tk export source git](tk_export_source_git.md) - Export GitRepository sources in YAML format
|
||||
* [tk export source helm](tk_export_source_helm.md) - Export HelmRepository sources in YAML format
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ tk export source git [name] [flags]
|
||||
|
||||
```
|
||||
# Export all GitRepository sources
|
||||
export source git --all > sources.yaml
|
||||
tk export source git --all > sources.yaml
|
||||
|
||||
# Export a GitRepository source including the SSH key pair or basic auth credentials
|
||||
export source git my-private-repo --with-credentials > source.yaml
|
||||
tk export source git my-private-repo --with-credentials > source.yaml
|
||||
|
||||
```
|
||||
|
||||
@@ -30,13 +30,12 @@ tk export source git [name] [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--all select all resources
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--with-credentials include credential secrets
|
||||
--all select all resources
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--with-credentials include credential secrets
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
44
docs/cmd/tk_export_source_helm.md
Normal file
44
docs/cmd/tk_export_source_helm.md
Normal file
@@ -0,0 +1,44 @@
|
||||
## tk export source helm
|
||||
|
||||
Export HelmRepository sources in YAML format
|
||||
|
||||
### Synopsis
|
||||
|
||||
The export source git command exports on or all HelmRepository sources in YAML format.
|
||||
|
||||
```
|
||||
tk export source helm [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Export all HelmRepository sources
|
||||
tk export source helm --all > sources.yaml
|
||||
|
||||
# Export a HelmRepository source including the basic auth credentials
|
||||
tk export source helm my-private-repo --with-credentials > source.yaml
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helm
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--all select all resources
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--with-credentials include credential secrets
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk export source](tk_export_source.md) - Export sources
|
||||
|
||||
@@ -15,16 +15,16 @@ The get sub-commands print the statuses of sources and resources.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk get kustomizations](tk_get_kustomizations.md) - Get Kustomization source statuses
|
||||
* [tk get helmreleases](tk_get_helmreleases.md) - Get HelmRelease statuses
|
||||
* [tk get kustomizations](tk_get_kustomizations.md) - Get Kustomization statuses
|
||||
* [tk get sources](tk_get_sources.md) - Get source statuses
|
||||
|
||||
|
||||
39
docs/cmd/tk_get_helmreleases.md
Normal file
39
docs/cmd/tk_get_helmreleases.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## tk get helmreleases
|
||||
|
||||
Get HelmRelease statuses
|
||||
|
||||
### Synopsis
|
||||
|
||||
The get helmreleases command prints the statuses of the resources.
|
||||
|
||||
```
|
||||
tk get helmreleases [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# List all Helm releases and their status
|
||||
tk get helmreleases
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helmreleases
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk get](tk_get.md) - Get sources and resources
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## tk get kustomizations
|
||||
|
||||
Get Kustomization source statuses
|
||||
Get Kustomization statuses
|
||||
|
||||
### Synopsis
|
||||
|
||||
@@ -10,6 +10,14 @@ The get kustomizations command prints the statuses of the resources.
|
||||
tk get kustomizations [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# List all kustomizations and their status
|
||||
tk get kustomizations
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
@@ -19,11 +27,10 @@ tk get kustomizations [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -15,15 +15,15 @@ The get source sub-commands print the statuses of the sources.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk get](tk_get.md) - Get sources and resources
|
||||
* [tk get sources git](tk_get_sources_git.md) - Get GitRepository source statuses
|
||||
* [tk get sources helm](tk_get_sources_helm.md) - Get HelmRepository source statuses
|
||||
|
||||
|
||||
@@ -10,6 +10,14 @@ The get sources git command prints the status of the GitRepository sources.
|
||||
tk get sources git [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# List all Git repositories and their status
|
||||
tk get sources git
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
@@ -19,11 +27,10 @@ tk get sources git [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
39
docs/cmd/tk_get_sources_helm.md
Normal file
39
docs/cmd/tk_get_sources_helm.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## tk get sources helm
|
||||
|
||||
Get HelmRepository source statuses
|
||||
|
||||
### Synopsis
|
||||
|
||||
The get sources helm command prints the status of the HelmRepository sources.
|
||||
|
||||
```
|
||||
tk get sources helm [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# List all Helm repositories and their status
|
||||
tk get sources helm
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helm
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk get sources](tk_get_sources.md) - Get source statuses
|
||||
|
||||
@@ -15,33 +15,39 @@ tk install [flags]
|
||||
|
||||
```
|
||||
# Install the latest version in the gitops-systems namespace
|
||||
install --version=master --namespace=gitops-systems
|
||||
tk install --version=latest --namespace=gitops-systems
|
||||
|
||||
# Dry-run install for a specific version and a series of components
|
||||
install --dry-run --version=0.0.1 --components="source-controller,kustomize-controller"
|
||||
tk install --dry-run --version=v0.0.7 --components="source-controller,kustomize-controller"
|
||||
|
||||
# Dry-run install with manifests preview
|
||||
install --dry-run --verbose
|
||||
tk install --dry-run --verbose
|
||||
|
||||
# Write install manifests to file
|
||||
tk install --export > gitops-system.yaml
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--dry-run only print the object that would be applied
|
||||
-h, --help help for install
|
||||
--manifests string path to the manifest directory, dev only
|
||||
-v, --version string toolkit tag or branch (default "master")
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
|
||||
--dry-run only print the object that would be applied
|
||||
--export write the install manifests to stdout and exit
|
||||
-h, --help help for install
|
||||
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
|
||||
--manifests string path to the manifest directory, dev only
|
||||
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
|
||||
-v, --version string toolkit version (default "latest")
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
30
docs/cmd/tk_reconcile.md
Normal file
30
docs/cmd/tk_reconcile.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## tk reconcile
|
||||
|
||||
Reconcile sources and resources
|
||||
|
||||
### Synopsis
|
||||
|
||||
The reconcile sub-commands trigger a reconciliation of sources and resources.
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for reconcile
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk reconcile helmrelease](tk_reconcile_helmrelease.md) - Reconcile a HelmRelease resource
|
||||
* [tk reconcile kustomization](tk_reconcile_kustomization.md) - Reconcile a Kustomization resource
|
||||
* [tk reconcile source](tk_reconcile_source.md) - Reconcile sources
|
||||
|
||||
44
docs/cmd/tk_reconcile_helmrelease.md
Normal file
44
docs/cmd/tk_reconcile_helmrelease.md
Normal file
@@ -0,0 +1,44 @@
|
||||
## tk reconcile helmrelease
|
||||
|
||||
Reconcile a HelmRelease resource
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
The reconcile kustomization command triggers a reconciliation of a HelmRelease resource and waits for it to finish.
|
||||
|
||||
```
|
||||
tk reconcile helmrelease [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Trigger a HelmRelease apply outside of the reconciliation interval
|
||||
tk reconcile hr podinfo
|
||||
|
||||
# Trigger a reconciliation of the HelmRelease's source and apply changes
|
||||
tk reconcile hr podinfo --with-source
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helmrelease
|
||||
--with-source reconcile HelmRelease source
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk reconcile](tk_reconcile.md) - Reconcile sources and resources
|
||||
|
||||
44
docs/cmd/tk_reconcile_kustomization.md
Normal file
44
docs/cmd/tk_reconcile_kustomization.md
Normal file
@@ -0,0 +1,44 @@
|
||||
## tk reconcile kustomization
|
||||
|
||||
Reconcile a Kustomization resource
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
The reconcile kustomization command triggers a reconciliation of a Kustomization resource and waits for it to finish.
|
||||
|
||||
```
|
||||
tk reconcile kustomization [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Trigger a Kustomization apply outside of the reconciliation interval
|
||||
tk reconcile kustomization podinfo
|
||||
|
||||
# Trigger a sync of the Kustomization's source and apply changes
|
||||
tk reconcile kustomization podinfo --with-source
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for kustomization
|
||||
--with-source reconcile kustomization source
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk reconcile](tk_reconcile.md) - Reconcile sources and resources
|
||||
|
||||
29
docs/cmd/tk_reconcile_source.md
Normal file
29
docs/cmd/tk_reconcile_source.md
Normal file
@@ -0,0 +1,29 @@
|
||||
## tk reconcile source
|
||||
|
||||
Reconcile sources
|
||||
|
||||
### Synopsis
|
||||
|
||||
The reconcile source sub-commands trigger a reconciliation of sources.
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for source
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk reconcile](tk_reconcile.md) - Reconcile sources and resources
|
||||
* [tk reconcile source git](tk_reconcile_source_git.md) - Reconcile a GitRepository source
|
||||
* [tk reconcile source helm](tk_reconcile_source_helm.md) - Reconcile a HelmRepository source
|
||||
|
||||
39
docs/cmd/tk_reconcile_source_git.md
Normal file
39
docs/cmd/tk_reconcile_source_git.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## tk reconcile source git
|
||||
|
||||
Reconcile a GitRepository source
|
||||
|
||||
### Synopsis
|
||||
|
||||
The reconcile source command triggers a reconciliation of a GitRepository resource and waits for it to finish.
|
||||
|
||||
```
|
||||
tk reconcile source git [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Trigger a git pull for an existing source
|
||||
tk reconcile source git podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for git
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk reconcile source](tk_reconcile_source.md) - Reconcile sources
|
||||
|
||||
39
docs/cmd/tk_reconcile_source_helm.md
Normal file
39
docs/cmd/tk_reconcile_source_helm.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## tk reconcile source helm
|
||||
|
||||
Reconcile a HelmRepository source
|
||||
|
||||
### Synopsis
|
||||
|
||||
The reconcile source command triggers a reconciliation of a HelmRepository resource and waits for it to finish.
|
||||
|
||||
```
|
||||
tk reconcile source helm [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Trigger a reconciliation for an existing source
|
||||
tk reconcile source helm podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helm
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk reconcile source](tk_reconcile_source.md) - Reconcile sources
|
||||
|
||||
@@ -15,15 +15,15 @@ The resume sub-commands resume a suspended resource.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk resume helmrelease](tk_resume_helmrelease.md) - Resume a suspended HelmRelease
|
||||
* [tk resume kustomization](tk_resume_kustomization.md) - Resume a suspended Kustomization
|
||||
|
||||
|
||||
40
docs/cmd/tk_resume_helmrelease.md
Normal file
40
docs/cmd/tk_resume_helmrelease.md
Normal file
@@ -0,0 +1,40 @@
|
||||
## tk resume helmrelease
|
||||
|
||||
Resume a suspended HelmRelease
|
||||
|
||||
### Synopsis
|
||||
|
||||
The resume command marks a previously suspended HelmRelease resource for reconciliation and waits for it to
|
||||
finish the apply.
|
||||
|
||||
```
|
||||
tk resume helmrelease [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Resume reconciliation for an existing Helm release
|
||||
tk resume hr podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helmrelease
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk resume](tk_resume.md) - Resume suspended resources
|
||||
|
||||
@@ -11,6 +11,14 @@ finish the apply.
|
||||
tk resume kustomization [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Resume reconciliation for an existing Kustomization
|
||||
tk resume ks podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
@@ -20,11 +28,10 @@ tk resume kustomization [name] [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -15,15 +15,15 @@ The suspend sub-commands suspend the reconciliation of a resource.
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk suspend helmrelease](tk_suspend_helmrelease.md) - Suspend reconciliation of HelmRelease
|
||||
* [tk suspend kustomization](tk_suspend_kustomization.md) - Suspend reconciliation of Kustomization
|
||||
|
||||
|
||||
39
docs/cmd/tk_suspend_helmrelease.md
Normal file
39
docs/cmd/tk_suspend_helmrelease.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## tk suspend helmrelease
|
||||
|
||||
Suspend reconciliation of HelmRelease
|
||||
|
||||
### Synopsis
|
||||
|
||||
The suspend command disables the reconciliation of a HelmRelease resource.
|
||||
|
||||
```
|
||||
tk suspend helmrelease [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Suspend reconciliation for an existing Helm release
|
||||
tk suspend hr podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for helmrelease
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk suspend](tk_suspend.md) - Suspend resources
|
||||
|
||||
@@ -10,6 +10,14 @@ The suspend command disables the reconciliation of a Kustomization resource.
|
||||
tk suspend kustomization [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Suspend reconciliation for an existing Kustomization
|
||||
tk suspend ks podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
@@ -19,11 +27,10 @@ tk suspend kustomization [name] [flags]
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
## tk sync
|
||||
|
||||
Synchronize sources and resources
|
||||
|
||||
### Synopsis
|
||||
|
||||
The sync sub-commands trigger a reconciliation of sources and resources.
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for sync
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
|
||||
* [tk sync kustomization](tk_sync_kustomization.md) - Synchronize a Kustomization resource
|
||||
* [tk sync source](tk_sync_source.md) - Synchronize sources
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
## tk sync kustomization
|
||||
|
||||
Synchronize a Kustomization resource
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
The sync kustomization command triggers a reconciliation of a Kustomization resource and waits for it to finish.
|
||||
|
||||
```
|
||||
tk sync kustomization [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Trigger a Kustomization apply outside of the reconciliation interval
|
||||
sync kustomization podinfo
|
||||
|
||||
# Trigger a sync of the Kustomization's source and apply changes
|
||||
sync kustomization podinfo --with-source
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for kustomization
|
||||
--with-source synchronize kustomization source
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk sync](tk_sync.md) - Synchronize sources and resources
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
## tk sync source
|
||||
|
||||
Synchronize sources
|
||||
|
||||
### Synopsis
|
||||
|
||||
The sync source sub-commands trigger a reconciliation of sources.
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for source
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk sync](tk_sync.md) - Synchronize sources and resources
|
||||
* [tk sync source git](tk_sync_source_git.md) - Synchronize a GitRepository source
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
## tk sync source git
|
||||
|
||||
Synchronize a GitRepository source
|
||||
|
||||
### Synopsis
|
||||
|
||||
The sync source command triggers a reconciliation of a GitRepository resource and waits for it to finish.
|
||||
|
||||
```
|
||||
tk sync source git [name] [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
# Trigger a git pull for an existing source
|
||||
sync source git podinfo
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for git
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [tk sync source](tk_sync_source.md) - Synchronize sources
|
||||
|
||||
@@ -14,31 +14,30 @@ tk uninstall [flags]
|
||||
|
||||
```
|
||||
# Dry-run uninstall of all components
|
||||
uninstall --dry-run --namespace=gitops-system
|
||||
tk uninstall --dry-run --namespace=gitops-system
|
||||
|
||||
# Uninstall all components and delete custom resource definitions
|
||||
uninstall --crds --namespace=gitops-system
|
||||
tk uninstall --resources --crds --namespace=gitops-system
|
||||
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--crds removes all CRDs previously installed
|
||||
--dry-run only print the object that would be deleted
|
||||
-h, --help help for uninstall
|
||||
--kustomizations removes all Kustomizations previously installed
|
||||
-s, --silent delete components without asking for confirmation
|
||||
--crds removes all CRDs previously installed
|
||||
--dry-run only print the object that would be deleted
|
||||
-h, --help help for uninstall
|
||||
--resources removes custom resources such as Kustomizations, GitRepositories and HelmRepositories
|
||||
-s, --silent delete components without asking for confirmation
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
|
||||
--namespace string the namespace scope for this operation (default "gitops-system")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--verbose print generated objects
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
25
docs/components/helm/controller.md
Normal file
25
docs/components/helm/controller.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Helm Controller
|
||||
|
||||
The Helm Controller is a Kubernetes operator, allowing one to declaratively manage Helm chart
|
||||
releases with Kubernetes manifests.
|
||||
|
||||

|
||||
|
||||
The desired state of a Helm release is described through a Kubernetes Custom Resource named `HelmRelease`.
|
||||
Based on the creation, mutation or removal of a HelmRelease resource in the cluster,
|
||||
Helm actions are performed by the controller.
|
||||
|
||||
Features:
|
||||
|
||||
- Watches for `HelmRelease` objects and generates `HelmChart` objects
|
||||
- Fetches artifacts produced by [source-controller](../source/controller.md) from `HelmChart` objects
|
||||
- Watches `HelmChart` objects for revision changes (semver ranges)
|
||||
- Performs Helm v3 actions including Helm tests as configured in the `HelmRelease` objects
|
||||
- Runs Helm install/upgrade in a specific order, taking into account the depends-on relationship
|
||||
- Prunes Helm releases removed from cluster (garbage collection)
|
||||
- Reports Helm releases status (alerting provided by [notification-controller](../notification/controller.md))
|
||||
|
||||
Links:
|
||||
|
||||
- Source code [fluxcd/helm-controller](https://github.com/fluxcd/helm-controller)
|
||||
- Specification [docs](https://github.com/fluxcd/helm-controller/tree/master/docs/spec)
|
||||
@@ -1,14 +1,15 @@
|
||||
# Notification Controller
|
||||
|
||||
The Notification Controller is a Kubernetes operator,
|
||||
specialized in dispatching events to external systems such as
|
||||
Slack, Microsoft Teams, Discord and Rocket chat.
|
||||
The Notification Controller is a Kubernetes operator, specialized in handling inbound and outbound events.
|
||||
|
||||
The controller receives events via HTTP and dispatch them to external
|
||||
webhooks based on event severity and involved objects.
|
||||

|
||||
|
||||
The controller can be configured with Kubernetes custom resources that
|
||||
define how events are processed and where to dispatch them.
|
||||
The controller handles events coming from external systems (GitHub, GitLab, Bitbucket, Harbour, Jenkins, etc)
|
||||
and notifies the GitOps toolkit controllers about source changes.
|
||||
|
||||
The controller handles events emitted by the GitOps toolkit controllers (source, kustomize, helm)
|
||||
and dispatches them to external systems (Slack, Microsoft Teams, Discord, Rocker)
|
||||
based on event severity and involved objects.
|
||||
|
||||
Links:
|
||||
|
||||
|
||||
1
docs/contributing/index.md
Symbolic link
1
docs/contributing/index.md
Symbolic link
@@ -0,0 +1 @@
|
||||
../../CONTRIBUTING.md
|
||||
233
docs/dev-guides/source-watcher.md
Normal file
233
docs/dev-guides/source-watcher.md
Normal file
@@ -0,0 +1,233 @@
|
||||
# Watching for source changes
|
||||
|
||||
In this guide you'll be developing a Kubernetes controller with
|
||||
[Kubebuilder](https://github.com/kubernetes-sigs/kubebuilder)
|
||||
that subscribes to [GitRepository](../components/source/gitrepositories.md)
|
||||
events and reacts to revision changes by downloading the artifact produced by
|
||||
[source-controller](../components/source/controller.md).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
On your dev machine install the following tools:
|
||||
|
||||
* go >= 1.13
|
||||
* kubebuilder >= 2.3
|
||||
* kind >= 0.8
|
||||
* kubectl >= 1.18
|
||||
* kustomize >= 3.5
|
||||
* docker >= 19.03
|
||||
|
||||
## Install the GitOps Toolkit
|
||||
|
||||
Create a cluster for testing:
|
||||
|
||||
```sh
|
||||
kind create cluster --name dev
|
||||
```
|
||||
|
||||
Install the toolkit CLI:
|
||||
|
||||
```sh
|
||||
curl -s https://toolkit.fluxcd.io/install.sh | sudo bash
|
||||
```
|
||||
|
||||
Verify that your dev machine satisfies the prerequisites with:
|
||||
|
||||
```sh
|
||||
tk check --pre
|
||||
```
|
||||
|
||||
Install the toolkit controllers on the dev cluster:
|
||||
|
||||
```sh
|
||||
tk install
|
||||
```
|
||||
|
||||
## Clone the sample controller
|
||||
|
||||
You'll be using [stefanprodan/source-watcher](https://github.com/stefanprodan/source-watcher) as
|
||||
a template for developing your own controller. The source-watcher was scaffolded with `kubebuilder init`.
|
||||
|
||||
Clone the source-watcher repo:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/stefanprodan/source-watcher
|
||||
cd source-watcher
|
||||
```
|
||||
|
||||
Build the controller:
|
||||
|
||||
```sh
|
||||
make
|
||||
```
|
||||
|
||||
## Run the controller
|
||||
|
||||
Port forward to source-controller artifacts server:
|
||||
|
||||
```sh
|
||||
kubectl -n gitops-system port-forward svc/source-controller 8181:80
|
||||
```
|
||||
|
||||
Export the local address as `SOURCE_HOST`:
|
||||
|
||||
```sh
|
||||
export SOURCE_HOST=localhost:8181
|
||||
```
|
||||
|
||||
Run source-watcher locally:
|
||||
|
||||
```sh
|
||||
make run
|
||||
```
|
||||
|
||||
Create a Git source:
|
||||
|
||||
```sh
|
||||
tk create source git test \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--tag=4.0.0
|
||||
```
|
||||
|
||||
The source-watcher should log the revision:
|
||||
|
||||
```console
|
||||
New revision detected {"gitrepository": "gitops-system/test", "revision": "4.0.0/ab953493ee14c3c9800bda0251e0c507f9741408"}
|
||||
Extracted tarball into /var/folders/77/3y6x_p2j2g9fspdkzjbm5_s40000gn/T/test292235827: 123 files, 29 dirs (32.603415ms)
|
||||
Processing files...
|
||||
```
|
||||
|
||||
Change the Git tag:
|
||||
|
||||
```sh
|
||||
tk create source git test \
|
||||
--url=https://github.com/stefanprodan/podinfo \
|
||||
--tag=4.0.1
|
||||
```
|
||||
|
||||
The source-watcher should log the new revision:
|
||||
|
||||
```console
|
||||
New revision detected {"gitrepository": "gitops-system/test", "revision": "4.0.1/113360052b3153e439a0cf8de76b8e3d2a7bdf27"}
|
||||
```
|
||||
|
||||
The source-controller reports the revision under `GitRepository.Status.Artifact.Revision` in the format: `<branch|tag>/<commit>`.
|
||||
|
||||
## How it works
|
||||
|
||||
The [GitRepositoryWatcher](https://github.com/stefanprodan/source-watcher/blob/master/controllers/gitrepository_watcher.go)
|
||||
controller does the following:
|
||||
|
||||
* subscribes to `GitRepository` events
|
||||
* detects when the Git revision changes
|
||||
* downloads and extracts the source artifact
|
||||
* write to stdout the extracted file names
|
||||
|
||||
```go
|
||||
// GitRepositoryWatcher watches GitRepository objects for revision changes
|
||||
type GitRepositoryWatcher struct {
|
||||
client.Client
|
||||
Log logr.Logger
|
||||
Scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories,verbs=get;list;watch
|
||||
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories/status,verbs=get
|
||||
|
||||
func (r *GitRepositoryWatcher) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
// set timeout for the reconciliation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// get source object
|
||||
var repository sourcev1.GitRepository
|
||||
if err := r.Get(ctx, req.NamespacedName, &repository); err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
log := r.Log.WithValues(strings.ToLower(repository.Kind), req.NamespacedName)
|
||||
log.Info("New revision detected", "revision", repository.Status.Artifact.Revision)
|
||||
|
||||
// create tmp dir
|
||||
tmpDir, err := ioutil.TempDir("", repository.Name)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("unable to create temp dir, error: %w", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// download and extract artifact
|
||||
summary, err := r.fetchArtifact(ctx, repository, tmpDir)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("unable to fetch artifact, error: %w", err)
|
||||
}
|
||||
log.Info(summary)
|
||||
|
||||
// list artifact content
|
||||
files, err := ioutil.ReadDir(tmpDir)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("unable to list files, error: %w", err)
|
||||
}
|
||||
|
||||
// do something with the artifact content
|
||||
for _, f := range files {
|
||||
log.Info("Processing " + f.Name())
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *GitRepositoryWatcher) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&sourcev1.GitRepository{}).
|
||||
WithEventFilter(GitRepositoryRevisionChangePredicate{}).
|
||||
Complete(r)
|
||||
}
|
||||
```
|
||||
|
||||
To add the watcher to an existing project, copy the controller and the revision change predicate to your `controllers` dir:
|
||||
|
||||
* [gitrepository_watcher.go](https://github.com/stefanprodan/source-watcher/blob/master/controllers/gitrepository_watcher.go)
|
||||
* [gitrepository_predicate.go](https://github.com/stefanprodan/source-watcher/blob/master/controllers/gitrepository_predicate.go)
|
||||
|
||||
In your `main.go` init function, register the Source API schema:
|
||||
|
||||
```go
|
||||
import sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
_ = sourcev1.AddToScheme(scheme)
|
||||
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
```
|
||||
|
||||
Start the controller in the main function:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
|
||||
if err = (&controllers.GitRepositoryWatcher{
|
||||
Client: mgr.GetClient(),
|
||||
Log: ctrl.Log.WithName("controllers").WithName("GitRepositoryWatcher"),
|
||||
Scheme: mgr.GetScheme(),
|
||||
}).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "GitRepositoryWatcher")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Note that the watcher controller depends on Kubernetes client-go >= 1.18.
|
||||
Your `go.mod` should require controller-runtime v0.6 or newer:
|
||||
|
||||
```go
|
||||
require (
|
||||
k8s.io/apimachinery v0.18.4
|
||||
k8s.io/client-go v0.18.4
|
||||
sigs.k8s.io/controller-runtime v0.6.0
|
||||
)
|
||||
```
|
||||
|
||||
That's it! Happy hacking!
|
||||
BIN
docs/diagrams/helm-controller-alerts.png
Normal file
BIN
docs/diagrams/helm-controller-alerts.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
93
docs/faq/index.md
Normal file
93
docs/faq/index.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Frequently asked questions
|
||||
|
||||
## General questions
|
||||
|
||||
### What does the GitOps Toolkit mean for Flux?
|
||||
|
||||
Flux v1 is a monolithic do-it-all operator; the GitOps Toolkit separates the functionalities into specialized controllers.
|
||||
|
||||
Flux v2 will be a curated configuration of the GitOps Toolkit, which you can install and operate simply using the `tk` command. You can easily pick and choose the functionality you need and extend it to serve your own purposes.
|
||||
|
||||
The timeline we are looking at right now is:
|
||||
|
||||
1. Put Flux v1 into maintenance mode (no new features being added; bugfixes and CVEs patched only).
|
||||
1. Continue work on [GitOps Toolkit roadmap](https://toolkit.fluxcd.io/roadmap/).
|
||||
1. We will provide transition guides for specific user groups, e.g. users of Flux v1 in read-only mode, or of Helm Operator v1, etc. once the functionality is integrated in the GitOps Toolkit and it's deemed "ready".
|
||||
1. Once the use-cases of Flux v1 are covered, we will continue supporting Flux v1 for 6 months. This will be the transition period before it's considered unsupported.
|
||||
|
||||
### Why did you rewrite Flux?
|
||||
|
||||
The GitOps Toolkit implements its functionality in individual controllers, which allowed us to address long-standing feature requests much more easily.
|
||||
|
||||
By basing these controllers on modern Kubernetes tooling (`controller-runtime` libraries), they can be dynamically configured with Kubernetes custom resources either by cluster admins or by other automated tools -- and you get greatly increased observability.
|
||||
|
||||
This gave us the opportunity to build the GitOps Toolkit with the top Flux feature requests in mind:
|
||||
|
||||
- Supporting multiple source Git repositories
|
||||
- Operational insight through health checks, events and alerts
|
||||
- Multi-tenancy capabilities, like applying each source repository with its own set of permissions
|
||||
|
||||
On top of that, testing the GitOps Toolkit and understanding the codebase becomes a lot easier.
|
||||
|
||||
### What are significant new differences between Flux v1 and the GitOps Toolkit?
|
||||
|
||||
#### Reconciliation
|
||||
|
||||
Flux v1 | Toolkit component driven "Flux v2"
|
||||
---------------------------------- | ----------------------------------
|
||||
Limited to a single Git repository | Multiple Git repositories
|
||||
Declarative config via arguments in the Flux deployment | `GitRepository` custom resource, which produces an artifact which can be reconciled by other controllers
|
||||
Follow `HEAD` of Git branches | Supports Git branches, pinning on commits and tags, follow SemVer tag ranges
|
||||
Suspending of reconciliation by downscaling Flux deployment | Reconciliation can be paused per resource by suspending the `GitRepository`
|
||||
Credentials config via Arguments and/or Secret volume mounts in the Flux pod | Credentials config per `GitRepository` resource: SSH private key, HTTP/S username/password/token, OpenPGP public keys
|
||||
|
||||
#### `kustomize` support
|
||||
|
||||
Flux v1 | Toolkit component driven "Flux v2"
|
||||
---------------------------------- | ----------------------------------
|
||||
Declarative config through `.flux.yaml` files in the Git repository | Declarative config through a `Kustomization` custom resource, consuming the artifact from the GitRepository
|
||||
Manifests are generated via shell exec and then reconciled by `fluxd` | Generation, server-side validation, and reconciliation is handled by a specialised `kustomize-controller`
|
||||
Reconciliation using the service account of the Flux deployment | Support for service account impersonation
|
||||
Garbage collection needs cluster role binding for Flux to query the Kubernetes discovery API | Garbage collection needs no cluster role binding or access to Kubernetes discovery API
|
||||
Support for custom commands and generators executed by fluxd in a POSIX shell | No support for custom commands
|
||||
|
||||
#### Helm integration
|
||||
|
||||
Flux v1 | Toolkit component driven "Flux v2"
|
||||
---------------------------------- | ----------------------------------
|
||||
Declarative config in a single Helm custom resource | Declarative config through `HelmRepository`, `HelmChart` and `HelmRelease` custom resources
|
||||
Chart synchronisation embedded in the operator | Extensive release configuration options, and a reconciliation interval per source
|
||||
Support for fixed SemVer versions from Helm repositories | Support for SemVer ranges for `HelmChart` resources
|
||||
Git repository synchronisation on a global interval | Planned support for charts from GitRepository sources
|
||||
Limited observability via the status object of the HelmRelease resource | Better observability via the HelmRelease status object, Kubernetes events, and notifications
|
||||
Resource heavy, relatively slow | Better performance
|
||||
|
||||
#### Notifications, webhooks, observability
|
||||
|
||||
Flux v1 | Toolkit component driven "Flux v2"
|
||||
---------------------------------- | ----------------------------------
|
||||
Emits "custom Flux events" to a webhook endpoint | Emits Kubernetes events for all custom resources part of the Toolkit
|
||||
RPC endpoint can be configured to a 3rd party solution like FluxCloud to be forwarded as notifications to e.g. Slack | Toolkit components can be configured to POST the events to a `notification-controller` endpoint. Selective forwarding of POSTed events as notifications using `Provider` and `Alert` custom resources.
|
||||
Webhook receiver is a side-project | Webhook receiver, handling a wide range of platforms, is included
|
||||
Unstructured logging | Structured logging for all components
|
||||
Custom Prometheus metrics | Generic / common `controller-runtime` Prometheus metrics
|
||||
|
||||
### How can I get involved?
|
||||
|
||||
There are a variety of ways and we look forward to having you on board building the future of GitOps together:
|
||||
|
||||
- [Discuss the direction](https://github.com/fluxcd/toolkit/discussions) of the GitOps Toolkit with us
|
||||
- Join us in #flux-dev on the [CNCF Slack](https://slack.cncf.io)
|
||||
- Check out our [contributor docs](https://toolkit.fluxcd.io/contributing/)
|
||||
- Take a look at the [roadmap of the GitOps Toolkit](https://toolkit.fluxcd.io/roadmap/)
|
||||
|
||||
### Are there any breaking changes?
|
||||
|
||||
- In Flux v1 Kustomize support was implemented through `.flux.yaml` files in the Git repository. As indicated in the comparison table above, while this approach worked, we found it to be error-prone and hard to debug. The new [Kustomization CR](https://github.com/fluxcd/kustomize-controller/blob/master/docs/spec/v1alpha1/kustomization.md) should make troubleshooting much easier. Unfortunately we needed to drop the support for custom commands as running arbitrary shell scripts in-cluster poses serious security concerns.
|
||||
- Helm users: we redesigned the `HelmRelease` API and the automation will work quite differently, so upgrading to `HelmRelease` v2 will require a little work from you, but you will gain more flexibility, better observability and performance.
|
||||
|
||||
### Is the GitOps Toolkit related to the GitOps Engine?
|
||||
|
||||
In an announcement in August 2019, the expectation was set that the Flux project would integrate the GitOps Engine, then being factored out of ArgoCD. Since the result would be backward-incompatible, it would require a major version bump: Flux v2.
|
||||
|
||||
After experimentation and considerable thought, we (the maintainers) have found a path to Flux v2 that we think better serves our vision of GitOps: the GitOps Toolkit. In consequence, we do not now plan to integrate GitOps Engine into Flux.
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need two Kubernetes clusters version 1.14 or newer and kubectl version 1.18.
|
||||
You will need two Kubernetes clusters version 1.16 or newer and kubectl version 1.18.
|
||||
For a quick local test, you can use [Kubernetes kind](https://kind.sigs.k8s.io/docs/user/quick-start/).
|
||||
Any other Kubernetes setup will work as well though.
|
||||
|
||||
@@ -63,7 +63,7 @@ $ tk check --pre
|
||||
|
||||
► checking prerequisites
|
||||
✔ kubectl 1.18.3 >=1.18.0
|
||||
✔ kubernetes 1.18.2 >=1.14.0
|
||||
✔ kubernetes 1.18.2 >=1.16.0
|
||||
✔ prerequisites checks passed
|
||||
```
|
||||
|
||||
@@ -152,7 +152,7 @@ tk create kustomization webapp-common \
|
||||
--source=webapp \
|
||||
--path="./deploy/webapp/common" \
|
||||
--prune=true \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--interval=1h \
|
||||
--export > ./staging-cluster/webapp-common.yaml
|
||||
```
|
||||
@@ -165,7 +165,7 @@ tk create kustomization webapp-backend \
|
||||
--source=webapp \
|
||||
--path="./deploy/webapp/backend" \
|
||||
--prune=true \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--interval=10m \
|
||||
--health-check="Deployment/backend.webapp" \
|
||||
--health-check-timeout=2m \
|
||||
@@ -180,7 +180,7 @@ tk create kustomization webapp-frontend \
|
||||
--source=webapp \
|
||||
--path="./deploy/webapp/frontend" \
|
||||
--prune=true \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--interval=10m \
|
||||
--health-check="Deployment/frontend.webapp" \
|
||||
--health-check-timeout=2m \
|
||||
@@ -227,7 +227,7 @@ If you delete a kustomization from the `fleet-infra` repo, the reconciler will r
|
||||
were previously applied from that kustomization.
|
||||
|
||||
If you alter the webapp deployment using `kubectl edit`, the changes will be reverted to match
|
||||
the state described in git. When dealing with an incident, you can pause the recitation of a
|
||||
the state described in git. When dealing with an incident, you can pause the reconciliation of a
|
||||
kustomization with `tk suspend kustomization <name>`. Once the debugging session
|
||||
is over, you can re-enable the reconciliation with `tk resume kustomization <name>`.
|
||||
|
||||
@@ -278,7 +278,7 @@ tk create kustomization webapp \
|
||||
--source=webapp \
|
||||
--path="./deploy/overlays/production" \
|
||||
--prune=true \
|
||||
--validate=client \
|
||||
--validation=client \
|
||||
--interval=10m \
|
||||
--health-check="Deployment/frontend.production" \
|
||||
--health-check="Deployment/backend.production" \
|
||||
@@ -329,19 +329,19 @@ git add -A && git commit -m "update prod webapp" && git push
|
||||
Trigger a git sync:
|
||||
|
||||
```console
|
||||
$ tk sync ks gitops-system --with-source
|
||||
$ tk reconcile ks gitops-system --with-source
|
||||
|
||||
► annotating source gitops-system
|
||||
✔ source annotated
|
||||
◎ waiting for git sync
|
||||
✔ git sync completed
|
||||
◎ waiting for reconcilitation
|
||||
✔ git reconciliation completed
|
||||
✔ fetched revision master/d751ea264d48bf0db8b588d1d08184834ac8fec9
|
||||
◎ waiting for kustomization sync
|
||||
✔ kustomization sync completed
|
||||
◎ waiting for kustomization reconcilitation
|
||||
✔ kustomization reconcilitation completed
|
||||
✔ applied revision master/d751ea264d48bf0db8b588d1d08184834ac8fec9
|
||||
```
|
||||
|
||||
The kubectl equivalent is `kubectl -n gitops-system annotate gitrepository/gitops-system source.fluxcd.io/syncAt="$(date +%s)"`.
|
||||
The kubectl equivalent is `kubectl -n gitops-system annotate gitrepository/gitops-system fluxcd.io/reconcileAt="$(date +%s)"`.
|
||||
|
||||
Wait for the webapp to be upgraded:
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user