1
0
mirror of synced 2026-03-01 11:16:56 +00:00

Compare commits

..

139 Commits

Author SHA1 Message Date
stefanprodan
422724bd2d Publish manifests as release assets 2020-07-17 12:00:15 +03:00
Stefan Prodan
6cb7897f25 Merge pull request #99 from fluxcd/export-install-manifests
Add export option to tk install
2020-07-16 16:07:13 +03:00
stefanprodan
499ba15004 Add export option to tk install 2020-07-16 15:56:05 +03:00
Stefan Prodan
b04abe989e Merge pull request #97 from fluxcd/helm-webhooks
Add webhook receivers section to Helm guide
2020-07-16 12:46:49 +03:00
stefanprodan
ea576179f9 Add webhook receivers section to Helm guide 2020-07-16 12:39:53 +03:00
Stefan Prodan
116d53a978 Merge pull request #95 from fluxcd/docs/helm-controller-notifications
Document helm-controller notifications in guide
2020-07-16 11:56:15 +03:00
Stefan Prodan
32adbf2ec8 Merge pull request #96 from fluxcd/prep-release-v0.0.5
Update controllers and go modules
2020-07-16 11:39:36 +03:00
stefanprodan
c664484fda Update controllers and go modules
- update source-controller to v0.0.5
- update kustomize-controller to v0.0.4
- update notification-controller to v0.0.4
- update helm-controller to v0.0.1-alpha.2
2020-07-16 11:30:45 +03:00
Hidde Beydals
06906eba4c Document helm-controller notifications in guide 2020-07-16 09:50:59 +02:00
Hidde Beydals
d387ebf32d Merge pull request #92 from fluxcd/docs/helmrelease-guide
Add "Manging Helm releases" guide to menu
2020-07-14 16:12:00 +02:00
Hidde Beydals
f75556f33c Add "Manging Helm releases" guide to menu 2020-07-14 16:05:48 +02:00
Hidde Beydals
2cf09e4de6 Merge pull request #86 from fluxcd/docs/helmrelease-guide 2020-07-14 16:02:50 +02:00
Hidde Beydals
a5a3a9c586 Make existence of HelmChart visible 2020-07-14 15:55:23 +02:00
Hidde Beydals
746dfbd955 Managing Helm releases guide 2020-07-14 15:55:19 +02:00
Stefan Prodan
a8cbe4b05f Merge pull request #91 from fluxcd/notification-v0.0.3
Update notification-controller to v0.0.3
2020-07-14 15:36:02 +03:00
stefanprodan
fe86da0cde Update notification-controller to v0.0.3 2020-07-14 15:26:10 +03:00
Stefan Prodan
4c86a2c191 Merge pull request #90 from fluxcd/helm-suspend
Add helm suspend/resume commands
2020-07-14 15:05:21 +03:00
stefanprodan
8dc5db17ac Add helm suspend/resume commands 2020-07-14 14:00:59 +03:00
Stefan Prodan
549c3a190e Merge pull request #87 from fluxcd/helm-reconcile
Add reconcile helm commands
2020-07-14 13:40:41 +03:00
stefanprodan
7a68c4ccf3 Add reconcile helm commands 2020-07-14 13:34:00 +03:00
Stefan Prodan
bf8831b833 Merge pull request #85 from fluxcd/reconcile-cmd
Rename sync cmd to reconcile
2020-07-14 11:58:38 +03:00
stefanprodan
394227571f Rename sync cmd to reconcile 2020-07-14 11:45:15 +03:00
Stefan Prodan
bf67577073 Merge pull request #84 from fluxcd/default-components
Refactor install defaults
2020-07-14 11:19:31 +03:00
stefanprodan
e180611024 Refactor defaults
- add dedicated components flag for bootstrap/install/check
- extract defaults to vars
- update CLI docs
2020-07-14 11:02:37 +03:00
Hidde Beydals
43cfc55368 Merge pull request #83 from fluxcd/build/hc-api-spec
build: use correct v2alpha1 HelmRelease spec URL
2020-07-14 09:29:28 +02:00
Hidde Beydals
c03b7ea15d build: use correct v2alpha1 HelmRelease spec URL 2020-07-14 09:22:51 +02:00
Stefan Prodan
ddfedfb590 Merge pull request #82 from fluxcd/helm-controller
Add helm-controller installer and docs
2020-07-14 10:12:09 +03:00
stefanprodan
24418370f1 Add helm-controller docs 2020-07-14 09:33:52 +03:00
stefanprodan
02521b6964 Add helm-controller to installer 2020-07-13 18:44:54 +03:00
Stefan Prodan
16f693148b Merge pull request #81 from fluxcd/docs-source-watcher
Add source watcher dev guide
2020-07-09 09:17:51 +03:00
stefanprodan
0bf46cb63f Add source watcher dev guide 2020-07-08 17:23:09 +03:00
Stefan Prodan
2e38855396 Merge pull request #80 from fluxcd/docs-webhook-receivers
Add webhook receivers guide to docs
2020-07-07 13:20:38 +03:00
stefanprodan
97592a1387 Add webhook receivers guide to docs 2020-07-07 13:15:24 +03:00
Stefan Prodan
c61bf76c80 Merge pull request #79 from fluxcd/notification-controller-v0.0.1
Update notification controller to v0.0.1
2020-07-07 10:13:34 +03:00
stefanprodan
e95b137011 Mark events forwarding task as completed 2020-07-07 10:04:42 +03:00
stefanprodan
ad655183e0 Update notification-controller to v0.0.1 2020-07-07 10:03:34 +03:00
stefanprodan
789fd34c4a Update fluxcd/pkg to v0.0.2 2020-07-07 10:02:54 +03:00
Daniel Holbach
87bbbaa475 Merge pull request #77 from dholbach/understanding-toolkit
explain a bit more about Flux Toolkit
2020-07-03 14:18:06 +02:00
Daniel Holbach
a4ca813cf5 add symlink and make it work 2020-07-03 14:09:30 +02:00
Daniel Holbach
e8eef73212 explain a bit more about Flux Toolkit 2020-07-03 11:40:59 +02:00
Stefan Prodan
512d4a43cb Merge pull request #76 from fluxcd/source-events
Enable notifications for source events
2020-07-03 11:29:41 +03:00
stefanprodan
b9f7b1d175 Enable notifications for source events 2020-07-03 11:15:34 +03:00
Stefan Prodan
b7727e2659 Merge pull request #74 from fluxcd/docs-notifications
Add notifications guide
2020-07-02 15:13:03 +03:00
stefanprodan
229d1d8c6e Add notifications guide 2020-07-02 14:51:28 +03:00
Stefan Prodan
c0b18f85aa Merge pull request #73 from fluxcd/notification-controller
Add notification component
2020-07-02 13:43:15 +03:00
stefanprodan
b11b9588f8 Update tk docs 2020-07-02 13:35:30 +03:00
stefanprodan
633d028841 Update kustomize controller and enable events 2020-07-02 13:14:56 +03:00
stefanprodan
a744b304a0 Add notification controller to docs 2020-07-02 12:58:01 +03:00
stefanprodan
e594350307 Add notification controller to tk components 2020-07-02 12:52:55 +03:00
Stefan Prodan
ecf7a1eac1 Merge pull request #70 from fluxcd/fluxcd-pkg
Migrate to fluxcd/pkg
2020-06-30 17:32:38 +03:00
stefanprodan
4621afcb31 Migrate to fluxcd/pkg 2020-06-30 17:11:04 +03:00
Stefan Prodan
006c949941 Merge pull request #69 from fluxcd/docs-meta
Add metadata to docs website
2020-06-26 16:53:09 +03:00
stefanprodan
72e06ab337 Add metadata to docs website 2020-06-26 16:41:04 +03:00
Hidde Beydals
f4b2a32a23 Merge pull request #67 from fluxcd/log-interface
Create logger interface
2020-06-25 18:20:17 +02:00
Hidde Beydals
329e21fd78 Create logger interface 2020-06-25 18:05:15 +02:00
Hidde Beydals
5499d15402 Merge pull request #68 from fluxcd/sort-ecdsa-curves
Sort supported ECDSA curves names
2020-06-25 18:03:29 +02:00
Hidde Beydals
d7f8a05612 Sort supported ECDSA curves names
To ensure options are always printed in the same order.
2020-06-25 17:53:41 +02:00
Hidde Beydals
1f99a75049 Merge pull request #66 from fluxcd/docs/cli-examples
Improve CLI command descriptions
2020-06-25 15:58:33 +02:00
Hidde Beydals
21fd436621 Add descriptions to all CLI commands 2020-06-25 15:49:31 +02:00
Stefan Prodan
ebcbe98684 Merge pull request #65 from fluxcd/release-v0.0.1
Update controllers to v0.0.1
2020-06-25 12:27:05 +03:00
stefanprodan
0e437c1105 Update controllers to v0.0.1 2020-06-25 09:59:30 +03:00
Stefan Prodan
4b18f56f00 Merge pull request #64 from fluxcd/docs-roadmap
Add roadmap draft to docs
2020-06-24 16:30:42 +03:00
Stefan Prodan
fd7ab0a7fd Hidde's fixes to roadmap
Co-authored-by: Hidde Beydals <hiddeco@users.noreply.github.com>
2020-06-24 16:02:50 +03:00
stefanprodan
c3c84d0ea0 Add roadmap draft to docs 2020-06-24 15:26:38 +03:00
Stefan Prodan
43b00c5696 Merge pull request #63 from fluxcd/kubeconfig
Honour KUBECONFIG environment variable
2020-06-24 14:25:21 +03:00
stefanprodan
a9f4536de4 Add tk sub commands to docs nav 2020-06-24 09:25:59 +03:00
stefanprodan
892230280c Honour KUBECONFIG environment variable 2020-06-24 09:25:30 +03:00
Hidde Beydals
0969a0c42a Merge pull request #62 from fluxcd/docs/menu 2020-06-23 16:49:30 +02:00
Hidde Beydals
185143ecf6 Merge pull request #60 from fluxcd/docs/cli 2020-06-23 16:39:49 +02:00
Hidde Beydals
6e06f94a91 docs: mention interoperability CAPI providers 2020-06-23 16:35:37 +02:00
Hidde Beydals
9af0bc31c3 docs: create dedicated sections in components menu 2020-06-23 16:28:33 +02:00
Hidde Beydals
6bcbb13bfb docs: align copyright docs with copyright header 2020-06-23 16:25:55 +02:00
Hidde Beydals
9a6d48d038 docs: run doc gen as part of test target 2020-06-23 16:25:55 +02:00
Hidde Beydals
0e81f6c3af docs: disable autogen footer CLI docs 2020-06-23 16:25:55 +02:00
Stefan Prodan
353a2dd92b Merge pull request #61 from fluxcd/docs-features
Add target features and diagram to docs
2020-06-23 17:23:37 +03:00
stefanprodan
ee749236e1 Add target features and diagram to docs 2020-06-23 17:17:39 +03:00
Hidde Beydals
cf45401250 Merge pull request #59 from fluxcd/git/author-email
Use owner in Git author email
2020-06-23 13:38:15 +02:00
Hidde Beydals
15429160c7 Use owner in Git author email 2020-06-23 13:19:56 +02:00
Hidde Beydals
3ea7f31797 Merge pull request #58 from fluxcd/ux/reformat-msg 2020-06-23 13:03:44 +02:00
Hidde Beydals
dbfa2f9944 Improve cmd messages 2020-06-23 12:54:51 +02:00
Hidde Beydals
98cf176c81 Improve Git provider error messages 2020-06-23 12:25:40 +02:00
Hidde Beydals
39b00797d6 Merge pull request #55 from fluxcd/governance/copy-headers
Copyright headers
2020-06-23 11:35:09 +02:00
Hidde Beydals
1df5a36f84 Copyright headers 2020-06-23 11:25:38 +02:00
Stefan Prodan
1db3bb3d33 Merge pull request #54 from fluxcd/docs-components
Add toolkit components to docs
2020-06-23 12:10:45 +03:00
stefanprodan
807848b6bb Add git repositories and kustomizations docs 2020-06-23 11:46:11 +03:00
stefanprodan
917598acf8 Add toolkit components docs 2020-06-22 19:15:08 +03:00
Stefan Prodan
b8bddf6a39 Merge pull request #51 from fluxcd/docs-guide
Add get started guide
2020-06-22 17:19:05 +03:00
stefanprodan
da95b7559d Add cluster creation commands to docs 2020-06-22 14:02:34 +03:00
stefanprodan
041b475f49 Add workflow overview to get started guide 2020-06-22 11:23:34 +03:00
stefanprodan
c0a8604f90 Add production workflow to docs 2020-06-19 20:22:24 +03:00
Stefan Prodan
ce80bd521a Merge pull request #50 from fluxcd/docs-get-started
Add docs website
2020-06-19 18:17:27 +03:00
stefanprodan
e92615b3a8 Publish docs from master branch 2020-06-19 18:03:41 +03:00
stefanprodan
3d7349ee53 Generate cmd docs 2020-06-19 17:44:08 +03:00
stefanprodan
0935a637f9 Add prerequisites check to docs 2020-06-19 17:37:24 +03:00
stefanprodan
c23d40ca71 Add instruction for tk kubectl plugin 2020-06-19 17:27:32 +03:00
stefanprodan
9ffe908c66 Add docs intro 2020-06-19 17:00:10 +03:00
stefanprodan
45003436bf Publish docs website on toolkit.fluxcd.io 2020-06-19 16:07:29 +03:00
stefanprodan
5074ff2889 Add install script to website 2020-06-19 14:36:54 +03:00
stefanprodan
c1d7582461 Add get started guide 2020-06-18 21:26:31 +03:00
stefanprodan
186c7d5786 Publish mkdocs to gh-pages 2020-06-18 20:19:25 +03:00
Stefan Prodan
7a87d353cb Merge pull request #42 from fluxcd/gitlab
Implement Gitlab bootstrap
2020-06-18 12:30:09 +03:00
stefanprodan
badd2a102f Generate bootstrap docs 2020-06-18 12:03:49 +03:00
stefanprodan
d0a79c2b4c Use git package for bootstrap 2020-06-18 09:59:39 +03:00
stefanprodan
bd781bbcfb Extract git operations 2020-06-18 01:55:29 +03:00
stefanprodan
f3d50e158a Implement GitLab bootstrap 2020-06-18 00:32:32 +03:00
Stefan Prodan
34ada4113f Merge pull request #41 from fluxcd/gh-teams
Assign GitHub teams during bootstrap
2020-06-16 17:30:56 +03:00
stefanprodan
4f43b504f4 Assign GitHub teams during bootstrap 2020-06-16 16:09:37 +03:00
Stefan Prodan
62e4b03342 Merge pull request #40 from fluxcd/gh-deploy-key
Rotate GitHub deploy key during bootstrap
2020-06-15 10:25:37 +03:00
stefanprodan
dca7b0ba91 Recreate GitHub deploy key during bootstrap 2020-06-12 18:05:00 +03:00
Stefan Prodan
2a61befbfd Merge pull request #39 from fluxcd/bootstrap-path
Add target path to the bootstrap cmd
2020-06-12 16:11:09 +03:00
Stefan Prodan
287be26190 Merge pull request #38 from fluxcd/uninstall-ks
Add kustomizations removal to uninstall cmd
2020-06-12 15:59:42 +03:00
stefanprodan
4992e11383 Add target path to the bootstrap cmd 2020-06-12 15:57:34 +03:00
stefanprodan
727734850e Add kustomizations removal to uninstall cmd 2020-06-10 18:49:38 +03:00
Hidde Beydals
e042d25062 Merge pull request #37 from fluxcd/go-license
Add Go license to forked package
2020-06-10 12:19:14 +02:00
Hidde Beydals
ba7a11d0e5 Add Go license to forked package 2020-06-10 12:10:04 +02:00
Stefan Prodan
ecbcc8b6f1 Merge pull request #35 from fluxcd/release-v0.0.1-beta.2
Update controllers to v0.0.1-beta.2
2020-06-10 12:20:34 +03:00
stefanprodan
94f320336c Update controllers to v0.0.1-beta.2 2020-06-10 12:12:35 +03:00
Hidde Beydals
c27f53b5b1 Merge pull request #34 from fluxcd/inmemory-knownhosts
ssh: add in-memory knownhosts utilities
2020-06-09 18:50:33 +02:00
Hidde Beydals
134d819bdf ssh: add in-memory knownhosts utilities 2020-06-09 18:23:45 +02:00
Stefan Prodan
dc7c2ce56b Merge pull request #31 from fluxcd/bootstrap-github
Implement GitHub repository bootstrap
2020-06-09 17:00:27 +03:00
stefanprodan
0cd820e923 Add export for public git repos 2020-06-09 16:22:35 +03:00
stefanprodan
c047a4476e Add bootstrap docs 2020-06-09 16:14:04 +03:00
stefanprodan
51ca2ee9d8 Improve cluster sync wait 2020-06-09 16:12:40 +03:00
stefanprodan
e612a8a496 Implement SSH deploy key bootstrap 2020-06-09 15:24:36 +03:00
stefanprodan
e70d86e843 Fix SSH secret upsert 2020-06-09 15:23:19 +03:00
stefanprodan
1bc637a43f Add export flag to create commands 2020-06-09 13:52:21 +03:00
stefanprodan
f5b738198f Add support for GitHub Enterprise 2020-06-09 13:52:21 +03:00
stefanprodan
34ea89c3be Create GitHub repo if it doesn't exists 2020-06-09 13:52:21 +03:00
stefanprodan
d4cbc45e16 Add personal and public options to bootstrap 2020-06-09 13:52:21 +03:00
stefanprodan
59ae2f327c Implement bootstrap upgrade 2020-06-09 13:52:21 +03:00
stefanprodan
4ec5b7fc69 Implement GitHub repository bootstrap 2020-06-09 13:52:21 +03:00
Hidde Beydals
9e31bbe716 Merge pull request #32 from fluxcd/go-native-ssh 2020-06-09 12:49:51 +02:00
Hidde Beydals
65cfa6d347 Move port check to scanHostKey func 2020-06-09 12:42:37 +02:00
Hidde Beydals
9099ad3d8b Split cmd SSH/auth functions 2020-06-09 12:30:47 +02:00
Hidde Beydals
43876b5ab9 Make SSH host key utilities publicly accessible 2020-06-09 11:31:01 +02:00
Hidde Beydals
6017946144 Improve host key scanner, add Ed25519 generator 2020-06-09 11:30:57 +02:00
Hidde Beydals
3a8151bcc0 Add various custom flags 2020-06-08 20:06:54 +02:00
Hidde Beydals
2dfe88b82d Move ssh package from internal to pkg 2020-06-08 13:44:51 +02:00
Hidde Beydals
a332e12338 Replace SSH shell-outs with Go implementation 2020-06-06 21:42:54 +02:00
130 changed files with 4941 additions and 1005 deletions

44
.github/workflows/docs.yaml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: Publish docs via GitHub Pages
on:
push:
branches:
- docs*
- master
jobs:
build:
name: Deploy docs
runs-on: ubuntu-latest
steps:
- name: Checkout master
uses: actions/checkout@v1
- name: Copy assets
run: |
# source-controller CRDs
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/source-controller/master/docs/spec/v1alpha1/helmcharts.md > docs/components/source/helmcharts.md
# kustomize-controller CRDs
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
# helm-controller CRDs
curl https://raw.githubusercontent.com/fluxcd/helm-controller/master/docs/api/helmrelease.md > docs/components/helm/api.md
curl https://raw.githubusercontent.com/fluxcd/helm-controller/master/docs/spec/v2alpha1/helmreleases.md > docs/components/helm/helmreleases.md
# notification-controller CRDs
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
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/spec/v1alpha1/receiver.md > docs/components/notification/receiver.md
# install script
cp install/tk.sh docs/install.sh
- name: Deploy docs
uses: mhausenblas/mkdocs-deploy-gh-pages@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CUSTOM_DOMAIN: toolkit.fluxcd.io

View File

@@ -30,6 +30,7 @@ jobs:
- name: Check if working tree is dirty
run: |
if [[ $(git diff --stat) != '' ]]; then
git diff
echo 'run make test and commit changes'
exit 1
fi
@@ -40,7 +41,7 @@ jobs:
./bin/tk check --pre
- name: tk install --version
run: |
./bin/tk install --version=master --namespace=test --verbose
./bin/tk install --version=master --namespace=test --verbose --components="source-controller,kustomize-controller"
- name: tk uninstall
run: |
./bin/tk uninstall --namespace=test --crds --silent
@@ -68,7 +69,7 @@ jobs:
--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

View File

@@ -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
View File

@@ -13,4 +13,5 @@
# Dependency directories (remove the comment below to include it)
# vendor/
bin/
bin/
output/

View File

@@ -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,13 +14,13 @@ 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.
[#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)
@@ -57,7 +57,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 ..."
@@ -66,3 +66,16 @@ For Source Controller we prefer the following rules for good commit messages:
The [following article](https://chris.beams.io/posts/git-commit/#seven-rules)
has some more helpful advice on documenting your work.
## 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

View File

@@ -11,7 +11,7 @@ fmt:
vet:
go vet ./...
test: tidy fmt vet
test: tidy fmt vet docs
go test ./... -coverprofile cover.out
build:

View File

@@ -1,4 +1,4 @@
# toolkit
# GitOps Toolkit
[![e2e](https://github.com/fluxcd/toolkit/workflows/e2e/badge.svg)](https://github.com/fluxcd/toolkit/actions)
[![report](https://goreportcard.com/badge/github.com/fluxcd/toolkit)](https://goreportcard.com/report/github.com/fluxcd/toolkit)
@@ -7,11 +7,6 @@
Experimental toolkit for assembling CD pipelines the GitOps way.
![overview](docs/diagrams/tk-overview.png)
![overview](docs/diagrams/tk-feature.png)
Components:
* [Toolkit CLI](docs/cmd/tk.md)
* [Source Controller](https://github.com/fluxcd/source-controller)
* [Kustomize Controller](https://github.com/fluxcd/kustomize-controller)
To install the toolkit CLI, follow the [instructions](install/README.md).
To get started with the toolkit please read the [docs](https://toolkit.fluxcd.io/).

252
cmd/tk/bootstrap.go Normal file
View File

@@ -0,0 +1,252 @@
/*
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"
"net/url"
"os"
"path"
"path/filepath"
"sigs.k8s.io/yaml"
"strings"
"time"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
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"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var bootstrapCmd = &cobra.Command{
Use: "bootstrap",
Short: "Bootstrap toolkit components",
Long: "The bootstrap sub-commands bootstrap the toolkit components on the targeted Git provider.",
}
var (
bootstrapVersion string
bootstrapComponents []string
)
const (
bootstrapBranch = "master"
bootstrapInstallManifest = "toolkit-components.yaml"
bootstrapSourceManifest = "toolkit-source.yaml"
bootstrapKustomizationManifest = "toolkit-kustomization.yaml"
)
func init() {
bootstrapCmd.PersistentFlags().StringVarP(&bootstrapVersion, "version", "v", defaultVersion,
"toolkit tag or branch")
bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapComponents, "components", defaultComponents,
"list of components, accepts comma-separated values")
rootCmd.AddCommand(bootstrapCmd)
}
func generateInstallManifests(targetPath, namespace, tmpDir string) (string, error) {
tkDir := path.Join(tmpDir, ".tk")
defer os.RemoveAll(tkDir)
if err := os.MkdirAll(tkDir, os.ModePerm); err != nil {
return "", fmt.Errorf("generating manifests failed: %w", err)
}
if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, tkDir); err != nil {
return "", fmt.Errorf("generating manifests failed: %w", err)
}
manifestsDir := path.Join(tmpDir, targetPath, namespace)
if err := os.MkdirAll(manifestsDir, os.ModePerm); err != nil {
return "", fmt.Errorf("generating manifests failed: %w", err)
}
manifest := path.Join(manifestsDir, bootstrapInstallManifest)
if err := buildKustomization(tkDir, manifest); err != nil {
return "", fmt.Errorf("build kustomization failed: %w", err)
}
return manifest, nil
}
func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error {
command := fmt.Sprintf("kubectl apply -f %s", manifestPath)
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
return fmt.Errorf("install failed")
}
for _, deployment := range components {
command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
namespace, deployment, timeout.String())
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
return fmt.Errorf("install failed")
}
}
return nil
}
func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, interval time.Duration) error {
gvk := sourcev1.GroupVersion.WithKind("GitRepository")
gitRepository := sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: sourcev1.GitRepositorySpec{
URL: url,
Interval: metav1.Duration{
Duration: interval,
},
Reference: &sourcev1.GitRepositoryRef{
Branch: "master",
},
SecretRef: &corev1.LocalObjectReference{
Name: name,
},
},
}
gitData, err := yaml.Marshal(gitRepository)
if err != nil {
return err
}
if err := utils.writeFile(string(gitData), filepath.Join(tmpDir, targetPath, namespace, bootstrapSourceManifest)); err != nil {
return err
}
gvk = kustomizev1.GroupVersion.WithKind("Kustomization")
kustomization := kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: kustomizev1.KustomizationSpec{
Interval: metav1.Duration{
Duration: 10 * time.Minute,
},
Path: fmt.Sprintf("./%s", strings.TrimPrefix(targetPath, "./")),
Prune: true,
SourceRef: kustomizev1.CrossNamespaceObjectReference{
Kind: sourcev1.GitRepositoryKind,
Name: name,
},
},
}
ksData, err := yaml.Marshal(kustomization)
if err != nil {
return err
}
if err := utils.writeFile(string(ksData), filepath.Join(tmpDir, targetPath, namespace, bootstrapKustomizationManifest)); err != nil {
return err
}
return nil
}
func applySyncManifests(ctx context.Context, kubeClient client.Client, name, namespace, targetPath, tmpDir string) error {
command := fmt.Sprintf("kubectl apply -f %s", filepath.Join(tmpDir, targetPath, namespace))
if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
return err
}
logger.Waitingf("waiting for cluster sync")
if err := wait.PollImmediate(pollInterval, timeout,
isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
if err := wait.PollImmediate(pollInterval, timeout,
isKustomizationReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
return nil
}
func shouldInstallManifests(ctx context.Context, kubeClient client.Client, namespace string) bool {
namespacedName := types.NamespacedName{
Namespace: namespace,
Name: namespace,
}
var kustomization kustomizev1.Kustomization
if err := kubeClient.Get(ctx, namespacedName, &kustomization); err != nil {
return true
}
return kustomization.Status.LastAppliedRevision == ""
}
func shouldCreateDeployKey(ctx context.Context, kubeClient client.Client, namespace string) bool {
namespacedName := types.NamespacedName{
Namespace: namespace,
Name: namespace,
}
var existing corev1.Secret
if err := kubeClient.Get(ctx, namespacedName, &existing); err != nil {
return true
}
return false
}
func generateDeployKey(ctx context.Context, kubeClient client.Client, url *url.URL, namespace string) (string, error) {
pair, err := generateKeyPair(ctx)
if err != nil {
return "", err
}
hostKey, err := scanHostKey(ctx, url)
if err != nil {
return "", err
}
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
Namespace: namespace,
},
StringData: map[string]string{
"identity": string(pair.PrivateKey),
"identity.pub": string(pair.PublicKey),
"known_hosts": string(hostKey),
},
}
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
return "", err
}
return string(pair.PublicKey), nil
}

240
cmd/tk/bootstrap_github.go Normal file
View File

@@ -0,0 +1,240 @@
/*
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"
"net/url"
"os"
"path"
"time"
"github.com/spf13/cobra"
"github.com/fluxcd/pkg/git"
)
var bootstrapGitHubCmd = &cobra.Command{
Use: "github",
Short: "Bootstrap toolkit components in a GitHub repository",
Long: `The bootstrap github command creates the GitHub repository if it doesn't exists and
commits the toolkit components manifests to the master branch.
Then it configures the target cluster to synchronize with the repository.
If the toolkit components are present on the cluster,
the bootstrap command will perform an upgrade if needed.`,
Example: ` # Create a GitHub personal access token and export it as an env var
export GITHUB_TOKEN=<my-token>
# Run bootstrap for a private repo owned by a GitHub organization
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>
# Run bootstrap for a repository path
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
# Run bootstrap for a private repo hosted on GitHub Enterprise
bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
`,
RunE: bootstrapGitHubCmdRun,
}
var (
ghOwner string
ghRepository string
ghInterval time.Duration
ghPersonal bool
ghPrivate bool
ghHostname string
ghPath string
ghTeams []string
)
const (
ghDefaultPermission = "maintain"
)
func init() {
bootstrapGitHubCmd.Flags().StringVar(&ghOwner, "owner", "", "GitHub user or organization name")
bootstrapGitHubCmd.Flags().StringVar(&ghRepository, "repository", "", "GitHub repository name")
bootstrapGitHubCmd.Flags().StringArrayVar(&ghTeams, "team", []string{}, "GitHub team to be given maintainer access")
bootstrapGitHubCmd.Flags().BoolVar(&ghPersonal, "personal", false, "is personal repository")
bootstrapGitHubCmd.Flags().BoolVar(&ghPrivate, "private", true, "is private repository")
bootstrapGitHubCmd.Flags().DurationVar(&ghInterval, "interval", time.Minute, "sync interval")
bootstrapGitHubCmd.Flags().StringVar(&ghHostname, "hostname", git.GitHubDefaultHostname, "GitHub hostname")
bootstrapGitHubCmd.Flags().StringVar(&ghPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path")
bootstrapCmd.AddCommand(bootstrapGitHubCmd)
}
func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
ghToken := os.Getenv(git.GitHubTokenName)
if ghToken == "" {
return fmt.Errorf("%s environment variable not found", git.GitHubTokenName)
}
repository, err := git.NewRepository(ghRepository, ghOwner, ghHostname, ghToken, "tk", ghOwner+"@users.noreply.github.com")
if err != nil {
return err
}
provider := &git.GithubProvider{
IsPrivate: ghPrivate,
IsPersonal: ghPersonal,
}
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", namespace)
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// create GitHub repository if doesn't exists
logger.Actionf("connecting to %s", ghHostname)
changed, err := provider.CreateRepository(ctx, repository)
if err != nil {
return err
}
if changed {
logger.Successf("repository created")
}
withErrors := false
// add teams to org repository
if !ghPersonal {
for _, team := range ghTeams {
if changed, err := provider.AddTeam(ctx, repository, team, ghDefaultPermission); err != nil {
logger.Failuref(err.Error())
withErrors = true
} else if changed {
logger.Successf("%s team access granted", team)
}
}
}
// clone repository and checkout the master branch
if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil {
return err
}
logger.Successf("repository cloned")
// generate install manifests
logger.Generatef("generating manifests")
manifest, err := generateInstallManifests(ghPath, namespace, tmpDir)
if err != nil {
return err
}
// stage install manifests
changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests")
if err != nil {
return err
}
// push install manifests
if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("components manifests pushed")
} else {
logger.Successf("components are up to date")
}
// determine if repo synchronization is working
isInstall := shouldInstallManifests(ctx, kubeClient, namespace)
if isInstall {
// apply install manifests
logger.Actionf("installing components in %s namespace", namespace)
if err := applyInstallManifests(ctx, manifest, bootstrapComponents); err != nil {
return err
}
logger.Successf("install completed")
}
// setup SSH deploy key
if shouldCreateDeployKey(ctx, kubeClient, namespace) {
logger.Actionf("configuring deploy key")
u, err := url.Parse(repository.GetSSH())
if err != nil {
return fmt.Errorf("git URL parse failed: %w", err)
}
key, err := generateDeployKey(ctx, kubeClient, u, namespace)
if err != nil {
return fmt.Errorf("generating deploy key failed: %w", err)
}
keyName := "tk"
if ghPath != "" {
keyName = fmt.Sprintf("tk-%s", ghPath)
}
if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil {
return err
} else if changed {
logger.Successf("deploy key configured")
}
}
// configure repo synchronization
if isInstall {
// generate source and kustomization manifests
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, ghPath, tmpDir, ghInterval); err != nil {
return err
}
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests"); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("sync manifests pushed")
}
// apply manifests and waiting for sync
logger.Actionf("applying sync manifests")
if err := applySyncManifests(ctx, kubeClient, namespace, namespace, ghPath, tmpDir); err != nil {
return err
}
}
if withErrors {
return fmt.Errorf("bootstrap completed with errors")
}
logger.Successf("bootstrap finished")
return nil
}

214
cmd/tk/bootstrap_gitlab.go Normal file
View File

@@ -0,0 +1,214 @@
/*
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"
"net/url"
"os"
"path"
"time"
"github.com/spf13/cobra"
"github.com/fluxcd/pkg/git"
)
var bootstrapGitLabCmd = &cobra.Command{
Use: "gitlab",
Short: "Bootstrap toolkit components in a GitLab repository",
Long: `The bootstrap gitlab command creates the GitLab repository if it doesn't exists and
commits the toolkit components manifests to the master branch.
Then it configures the target cluster to synchronize with the repository.
If the toolkit components are present on the cluster,
the bootstrap command will perform an upgrade if needed.`,
Example: ` # Create a GitLab API token and export it as an env var
export GITLAB_TOKEN=<my-token>
# Run bootstrap for a private repo owned by a GitLab group
bootstrap gitlab --owner=<group> --repository=<repo name>
# Run bootstrap for a repository path
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
# Run bootstrap for a private repo hosted on a GitLab server
bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
`,
RunE: bootstrapGitLabCmdRun,
}
var (
glOwner string
glRepository string
glInterval time.Duration
glPersonal bool
glPrivate bool
glHostname string
glPath string
)
func init() {
bootstrapGitLabCmd.Flags().StringVar(&glOwner, "owner", "", "GitLab user or group name")
bootstrapGitLabCmd.Flags().StringVar(&glRepository, "repository", "", "GitLab repository name")
bootstrapGitLabCmd.Flags().BoolVar(&glPersonal, "personal", false, "is personal repository")
bootstrapGitLabCmd.Flags().BoolVar(&glPrivate, "private", true, "is private repository")
bootstrapGitLabCmd.Flags().DurationVar(&glInterval, "interval", time.Minute, "sync interval")
bootstrapGitLabCmd.Flags().StringVar(&glHostname, "hostname", git.GitLabDefaultHostname, "GitLab hostname")
bootstrapGitLabCmd.Flags().StringVar(&glPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path")
bootstrapCmd.AddCommand(bootstrapGitLabCmd)
}
func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
glToken := os.Getenv(git.GitLabTokenName)
if glToken == "" {
return fmt.Errorf("%s environment variable not found", git.GitLabTokenName)
}
repository, err := git.NewRepository(glRepository, glOwner, glHostname, glToken, "tk", glOwner+"@users.noreply.gitlab.com")
if err != nil {
return err
}
provider := &git.GitLabProvider{
IsPrivate: glPrivate,
IsPersonal: glPersonal,
}
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", namespace)
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// create GitLab project if doesn't exists
logger.Actionf("connecting to %s", glHostname)
changed, err := provider.CreateRepository(ctx, repository)
if err != nil {
return err
}
if changed {
logger.Successf("repository created")
}
// clone repository and checkout the master branch
if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil {
return err
}
logger.Successf("repository cloned")
// generate install manifests
logger.Generatef("generating manifests")
manifest, err := generateInstallManifests(glPath, namespace, tmpDir)
if err != nil {
return err
}
// stage install manifests
changed, err = repository.Commit(ctx, path.Join(glPath, namespace), "Add manifests")
if err != nil {
return err
}
// push install manifests
if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("components manifests pushed")
} else {
logger.Successf("components are up to date")
}
// determine if repo synchronization is working
isInstall := shouldInstallManifests(ctx, kubeClient, namespace)
if isInstall {
// apply install manifests
logger.Actionf("installing components in %s namespace", namespace)
if err := applyInstallManifests(ctx, manifest, bootstrapComponents); err != nil {
return err
}
logger.Successf("install completed")
}
// setup SSH deploy key
if shouldCreateDeployKey(ctx, kubeClient, namespace) {
logger.Actionf("configuring deploy key")
u, err := url.Parse(repository.GetSSH())
if err != nil {
return fmt.Errorf("git URL parse failed: %w", err)
}
key, err := generateDeployKey(ctx, kubeClient, u, namespace)
if err != nil {
return fmt.Errorf("generating deploy key failed: %w", err)
}
keyName := "tk"
if glPath != "" {
keyName = fmt.Sprintf("tk-%s", glPath)
}
if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil {
return err
} else if changed {
logger.Successf("deploy key configured")
}
}
// configure repo synchronization
if isInstall {
// generate source and kustomization manifests
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, glPath, tmpDir, glInterval); err != nil {
return err
}
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(glPath, namespace), "Add manifests"); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("sync manifests pushed")
}
// apply manifests and waiting for sync
logger.Actionf("applying sync manifests")
if err := applySyncManifests(ctx, kubeClient, namespace, namespace, glPath, tmpDir); err != nil {
return err
}
}
logger.Successf("bootstrap finished")
return nil
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -16,26 +32,27 @@ import (
var checkCmd = &cobra.Command{
Use: "check",
Short: "Check requirements and installation",
Long: `
The check command will perform a series of checks to validate that
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)
}
@@ -43,11 +60,8 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
logAction("checking prerequisites")
logger.Actionf("checking prerequisites")
checkFailed := false
if !sshCheck() {
checkFailed = true
}
if !kubectlCheck(ctx, ">=1.18.0") {
checkFailed = true
@@ -61,98 +75,83 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
if checkFailed {
os.Exit(1)
}
logSuccess("prerequisites checks passed")
logger.Successf("prerequisites checks passed")
return nil
}
logAction("checking controllers")
logger.Actionf("checking controllers")
if !componentsCheck() {
checkFailed = true
}
if checkFailed {
os.Exit(1)
}
logSuccess("all checks passed")
logger.Successf("all checks passed")
return nil
}
func sshCheck() bool {
ok := true
for _, cmd := range []string{"ssh-keygen", "ssh-keyscan"} {
_, err := exec.LookPath(cmd)
if err != nil {
logFailure("%s not found", cmd)
ok = false
} else {
logSuccess("%s found", cmd)
}
}
return ok
}
func kubectlCheck(ctx context.Context, version string) bool {
_, err := exec.LookPath("kubectl")
if err != nil {
logFailure("kubectl not found")
logger.Failuref("kubectl not found")
return false
}
command := "kubectl version --client --short | awk '{ print $3 }'"
output, err := utils.execCommand(ctx, ModeCapture, command)
if err != nil {
logFailure("kubectl version can't be determined")
logger.Failuref("kubectl version can't be determined")
return false
}
v, err := semver.ParseTolerant(output)
if err != nil {
logFailure("kubectl version can't be parsed")
logger.Failuref("kubectl version can't be parsed")
return false
}
rng, _ := semver.ParseRange(version)
if !rng(v) {
logFailure("kubectl version must be %s", version)
logger.Failuref("kubectl version must be %s", version)
return false
}
logSuccess("kubectl %s %s", v.String(), version)
logger.Successf("kubectl %s %s", v.String(), version)
return true
}
func kubernetesCheck(version string) bool {
cfg, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
logFailure("kubernetes client initialization failed: %s", err.Error())
logger.Failuref("Kubernetes client initialization failed: %s", err.Error())
return false
}
client, err := kubernetes.NewForConfig(cfg)
if err != nil {
logFailure("kubernetes client initialization failed: %s", err.Error())
logger.Failuref("Kubernetes client initialization failed: %s", err.Error())
return false
}
ver, err := client.Discovery().ServerVersion()
if err != nil {
logFailure("kubernetes API call failed %s", err.Error())
logger.Failuref("Kubernetes API call failed: %s", err.Error())
return false
}
v, err := semver.ParseTolerant(ver.String())
if err != nil {
logFailure("kubernetes version can't be determined")
logger.Failuref("Kubernetes version can't be determined")
return false
}
rng, _ := semver.ParseRange(version)
if !rng(v) {
logFailure("kubernetes version must be %s", version)
logger.Failuref("Kubernetes version must be %s", version)
return false
}
logSuccess("kubernetes %s %s", v.String(), version)
logger.Successf("Kubernetes %s %s", v.String(), version)
return true
}
@@ -161,14 +160,14 @@ 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 {
logFailure("%s: %s", deployment, strings.TrimSuffix(output, "\n"))
logger.Failuref("%s: %s", deployment, strings.TrimSuffix(output, "\n"))
ok = false
} else {
logSuccess("%s is healthy", deployment)
logger.Successf("%s is healthy", deployment)
}
}
return ok

View File

@@ -1,3 +1,19 @@
/*
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 (

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -8,14 +24,17 @@ import (
var createCmd = &cobra.Command{
Use: "create",
Short: "Create commands",
Short: "Create or update sources and resources",
Long: "The create sub-commands generate sources and resources.",
}
var (
interval time.Duration
export bool
)
func init() {
createCmd.PersistentFlags().DurationVarP(&interval, "interval", "", time.Minute, "source sync interval")
createCmd.PersistentFlags().BoolVar(&export, "export", false, "export in YAML format to stdout")
rootCmd.AddCommand(createCmd)
}

View File

@@ -1,13 +1,27 @@
/*
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"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
"strings"
"time"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
@@ -15,16 +29,17 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var createKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Create or update a kustomization resource",
Long: `
The kustomization source command generates a kustomization.kustomize.fluxcd.io resource for a given GitRepository source.
API spec: https://github.com/fluxcd/kustomize-controller/tree/master/docs/spec/v1alpha1`,
Example: ` # Create a kustomization from a source at a given path
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 \
--source=contour \
--path="./examples/contour/" \
@@ -35,7 +50,7 @@ API spec: https://github.com/fluxcd/kustomize-controller/tree/master/docs/spec/v
--health-check="DaemonSet/envoy.projectcontour" \
--health-check-timeout=3m
# Create a kustomization that depends on the previous one
# Create a Kustomization resource that depends on the previous one
create kustomization webapp \
--depends-on=contour \
--source=webapp \
@@ -44,7 +59,7 @@ API spec: https://github.com/fluxcd/kustomize-controller/tree/master/docs/spec/v
--interval=5m \
--validate=client
# Create a kustomization that runs under a service account
# Create a Kustomization resource that runs under a service account
create kustomization webapp \
--source=webapp \
--path="./deploy/overlays/staging" \
@@ -71,12 +86,12 @@ var (
func init() {
createKsCmd.Flags().StringVar(&ksSource, "source", "", "GitRepository name")
createKsCmd.Flags().StringVar(&ksPath, "path", "./", "path to the directory containing the kustomization file")
createKsCmd.Flags().StringVar(&ksPath, "path", "./", "path to the directory containing the Kustomization file")
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().StringArrayVar(&ksDependsOn, "depends-on", nil, "kustomization that must be ready before this kustomization can be applied")
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")
createCmd.AddCommand(createKsCmd)
@@ -106,9 +121,10 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
return err
}
logGenerate("generating kustomization")
if !export {
logger.Generatef("generating kustomization")
}
emptyAPIGroup := ""
kustomization := kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -121,10 +137,9 @@ 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,
@@ -171,18 +186,22 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
}
}
logAction("applying kustomization")
if export {
return exportKs(kustomization)
}
logger.Actionf("applying kustomization")
if err := upsertKustomization(ctx, kubeClient, kustomization); err != nil {
return err
}
logWaiting("waiting for kustomization sync")
logger.Waitingf("waiting for kustomization sync")
if err := wait.PollImmediate(pollInterval, timeout,
isKustomizationReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
logSuccess("kustomization %s is ready", name)
logger.Successf("kustomization %s is ready", name)
namespacedName := types.NamespacedName{
Namespace: namespace,
@@ -194,7 +213,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
}
if kustomization.Status.LastAppliedRevision != "" {
logSuccess("applied revision %s", kustomization.Status.LastAppliedRevision)
logger.Successf("applied revision %s", kustomization.Status.LastAppliedRevision)
} else {
return fmt.Errorf("kustomization sync failed")
}
@@ -215,7 +234,7 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client, kustomiz
if err := kubeClient.Create(ctx, &kustomization); err != nil {
return err
} else {
logSuccess("kustomization created")
logger.Successf("kustomization created")
return nil
}
}
@@ -227,7 +246,7 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client, kustomiz
return err
}
logSuccess("kustomization updated")
logger.Successf("kustomization updated")
return nil
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var createSourceCmd = &cobra.Command{
Use: "source",
Short: "Create source commands",
Short: "Create or update sources",
Long: "The create source sub-commands generate sources.",
}
func init() {

View File

@@ -1,28 +1,48 @@
/*
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"
"crypto/elliptic"
"fmt"
"io/ioutil"
"net/url"
"os"
"time"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/manifoldco/promptui"
"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"
"strings"
"github.com/fluxcd/pkg/ssh"
)
var createSourceGitCmd = &cobra.Command{
Use: "git [name]",
Short: "Create or update a git source",
Short: "Create or update a GitRepository source",
Long: `
The create source command generates a GitRepository resource and waits for it to sync.
The create source git command generates a GitRepository resource and waits for it to sync.
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
@@ -40,11 +60,19 @@ For private Git repositories, the basic authentication credentials are stored in
--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 a source from a Git repository using SSH authentication
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 \
--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 \
--url=https://github.com/stefanprodan/podinfo \
@@ -55,12 +83,15 @@ For private Git repositories, the basic authentication credentials are stored in
}
var (
sourceGitURL string
sourceGitBranch string
sourceGitTag string
sourceGitSemver string
sourceGitUsername string
sourceGitPassword string
sourceGitURL string
sourceGitBranch string
sourceGitTag string
sourceGitSemver string
sourceGitUsername string
sourceGitPassword string
sourceGitKeyAlgorithm PublicKeyAlgorithm = "rsa"
sourceGitRSABits RSAKeyBits = 2048
sourceGitECDSACurve = ECDSACurve{elliptic.P384()}
)
func init() {
@@ -70,6 +101,9 @@ func init() {
createSourceGitCmd.Flags().StringVar(&sourceGitSemver, "tag-semver", "", "git tag semver range")
createSourceGitCmd.Flags().StringVarP(&sourceGitUsername, "username", "u", "", "basic authentication username")
createSourceGitCmd.Flags().StringVarP(&sourceGitPassword, "password", "p", "", "basic authentication password")
createSourceGitCmd.Flags().Var(&sourceGitKeyAlgorithm, "ssh-key-algorithm", sourceGitKeyAlgorithm.Description())
createSourceGitCmd.Flags().Var(&sourceGitRSABits, "ssh-rsa-bits", sourceGitRSABits.Description())
createSourceGitCmd.Flags().Var(&sourceGitECDSACurve, "ssh-ecdsa-curve", sourceGitECDSACurve.Description())
createSourceCmd.AddCommand(createSourceGitCmd)
}
@@ -98,25 +132,11 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
withAuth := false
if strings.HasPrefix(sourceGitURL, "ssh") {
if err := generateSSH(ctx, name, u.Host, tmpDir); err != nil {
return err
}
withAuth = true
} else if sourceGitUsername != "" && sourceGitPassword != "" {
if err := generateBasicAuth(ctx, name); err != nil {
return err
}
withAuth = true
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
if withAuth {
logSuccess("authentication configured")
}
logGenerate("generating source")
gitRepository := sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -131,12 +151,6 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
},
}
if withAuth {
gitRepository.Spec.SecretRef = &corev1.LocalObjectReference{
Name: name,
}
}
if sourceGitSemver != "" {
gitRepository.Spec.Reference.SemVer = sourceGitSemver
} else if sourceGitTag != "" {
@@ -145,23 +159,94 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
gitRepository.Spec.Reference.Branch = sourceGitBranch
}
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
if export {
return exportGit(gitRepository)
}
logAction("applying source")
withAuth := false
// TODO(hidde): move all auth prep to separate func?
if u.Scheme == "ssh" {
logger.Actionf("generating deploy key pair")
pair, err := generateKeyPair(ctx)
if err != nil {
return err
}
fmt.Printf("%s", pair.PublicKey)
prompt := promptui.Prompt{
Label: "Have you added the deploy key to your repository",
IsConfirm: true,
}
if _, err := prompt.Run(); err != nil {
return fmt.Errorf("aborting")
}
logger.Actionf("collecting preferred public key from SSH server")
hostKey, err := scanHostKey(ctx, u)
if err != nil {
return err
}
logger.Successf("collected public key from SSH server:")
fmt.Printf("%s", hostKey)
logger.Actionf("applying secret with keys")
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
StringData: map[string]string{
"identity": string(pair.PrivateKey),
"identity.pub": string(pair.PublicKey),
"known_hosts": string(hostKey),
},
}
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
return err
}
withAuth = true
} else if sourceGitUsername != "" && sourceGitPassword != "" {
logger.Actionf("applying secret with basic auth credentials")
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
StringData: map[string]string{
"username": sourceGitUsername,
"password": sourceGitPassword,
},
}
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
return err
}
withAuth = true
}
if withAuth {
logger.Successf("authentication configured")
}
logger.Generatef("generating source")
if withAuth {
gitRepository.Spec.SecretRef = &corev1.LocalObjectReference{
Name: name,
}
}
logger.Actionf("applying source")
if err := upsertGitRepository(ctx, kubeClient, gitRepository); err != nil {
return err
}
logWaiting("waiting for git sync")
logger.Waitingf("waiting for git sync")
if err := wait.PollImmediate(pollInterval, timeout,
isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
logSuccess("git sync completed")
logger.Successf("git sync completed")
namespacedName := types.NamespacedName{
Namespace: namespace,
@@ -173,7 +258,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
if gitRepository.Status.Artifact != nil {
logSuccess("fetched revision %s", gitRepository.Status.Artifact.Revision)
logger.Successf("fetched revision: %s", gitRepository.Status.Artifact.Revision)
} else {
return fmt.Errorf("git sync failed, artifact not found")
}
@@ -181,55 +266,59 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
return nil
}
func generateBasicAuth(ctx context.Context, name string) error {
logAction("saving credentials")
credentials := fmt.Sprintf("--from-literal=username='%s' --from-literal=password='%s'",
sourceGitUsername, sourceGitPassword)
secret := fmt.Sprintf("kubectl -n %s create secret generic %s %s --dry-run=client -oyaml | kubectl apply -f-",
namespace, name, credentials)
if _, err := utils.execCommand(ctx, ModeOS, secret); err != nil {
return fmt.Errorf("kubectl create secret failed")
func generateKeyPair(ctx context.Context) (*ssh.KeyPair, error) {
var keyGen ssh.KeyPairGenerator
switch algorithm := sourceGitKeyAlgorithm.String(); algorithm {
case "rsa":
keyGen = ssh.NewRSAGenerator(int(sourceGitRSABits))
case "ecdsa":
keyGen = ssh.NewECDSAGenerator(sourceGitECDSACurve.Curve)
case "ed25519":
keyGen = ssh.NewEd25519Generator()
default:
return nil, fmt.Errorf("unsupported public key algorithm: %s", algorithm)
}
return nil
pair, err := keyGen.Generate()
if err != nil {
return nil, fmt.Errorf("key pair generation failed, error: %w", err)
}
return pair, nil
}
func generateSSH(ctx context.Context, name, host, tmpDir string) error {
logGenerate("generating host key for %s", host)
func scanHostKey(ctx context.Context, url *url.URL) ([]byte, error) {
host := url.Host
if url.Port() == "" {
host = host + ":22"
}
hostKey, err := ssh.ScanHostKey(host, 30*time.Second)
if err != nil {
return nil, fmt.Errorf("SSH key scan for host %s failed, error: %w", host, err)
}
return hostKey, nil
}
command := fmt.Sprintf("ssh-keyscan %s > %s/known_hosts", host, tmpDir)
if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
return fmt.Errorf("ssh-keyscan failed")
func upsertSecret(ctx context.Context, kubeClient client.Client, secret corev1.Secret) error {
namespacedName := types.NamespacedName{
Namespace: secret.GetNamespace(),
Name: secret.GetName(),
}
logGenerate("generating deploy key")
command = fmt.Sprintf("ssh-keygen -b 2048 -t rsa -f %s/identity -q -N \"\"", tmpDir)
if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
return fmt.Errorf("ssh-keygen failed")
var existing corev1.Secret
err := kubeClient.Get(ctx, namespacedName, &existing)
if err != nil {
if errors.IsNotFound(err) {
if err := kubeClient.Create(ctx, &secret); err != nil {
return err
} else {
return nil
}
}
return err
}
command = fmt.Sprintf("cat %s/identity.pub", tmpDir)
if deployKey, err := utils.execCommand(ctx, ModeCapture, command); err != nil {
return fmt.Errorf("unable to read identity.pub: %w", err)
} else {
fmt.Print(deployKey)
}
prompt := promptui.Prompt{
Label: "Have you added the deploy key to your repository",
IsConfirm: true,
}
if _, err := prompt.Run(); err != nil {
return fmt.Errorf("aborting")
}
logAction("saving keys")
files := fmt.Sprintf("--from-file=%s/identity --from-file=%s/identity.pub --from-file=%s/known_hosts",
tmpDir, tmpDir, tmpDir)
secret := fmt.Sprintf("kubectl -n %s create secret generic %s %s --dry-run=client -oyaml | kubectl apply -f-",
namespace, name, files)
if _, err := utils.execCommand(ctx, ModeOS, secret); err != nil {
return fmt.Errorf("create secret failed")
existing.StringData = secret.StringData
if err := kubeClient.Update(ctx, &existing); err != nil {
return err
}
return nil
}
@@ -247,7 +336,7 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client, gitRepos
if err := kubeClient.Create(ctx, &gitRepository); err != nil {
return err
} else {
logSuccess("source created")
logger.Successf("source created")
return nil
}
}
@@ -259,7 +348,7 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client, gitRepos
return err
}
logSuccess("source updated")
logger.Successf("source updated")
return nil
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete commands",
Short: "Delete sources and resources",
Long: "The delete sub-commands delete sources and resources.",
}
var (

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -13,7 +29,8 @@ import (
var deleteKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Delete kustomization",
Short: "Delete a Kustomization resource",
Long: "The delete kustomization command deletes the given Kustomization from the cluster.",
RunE: deleteKsCmdRun,
}
@@ -48,7 +65,7 @@ func deleteKsCmdRun(cmd *cobra.Command, args []string) error {
if !deleteSilent {
if !kustomization.Spec.Suspend {
logWaiting("This action will remove the Kubernetes objects previously applied by the %s kustomization!", name)
logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s kustomization!", name)
}
prompt := promptui.Prompt{
Label: "Are you sure you want to delete this kustomization",
@@ -59,12 +76,12 @@ func deleteKsCmdRun(cmd *cobra.Command, args []string) error {
}
}
logAction("deleting kustomization %s in %s namespace", name, namespace)
logger.Actionf("deleting kustomization %s in %s namespace", name, namespace)
err = kubeClient.Delete(ctx, &kustomization)
if err != nil {
return err
}
logSuccess("kustomization deleted")
logger.Successf("kustomization deleted")
return nil
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var deleteSourceCmd = &cobra.Command{
Use: "source",
Short: "Delete sources commands",
Short: "Delete sources",
Long: "The delete source sub-commands delete sources.",
}
func init() {

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -12,7 +28,8 @@ import (
var deleteSourceGitCmd = &cobra.Command{
Use: "git [name]",
Short: "Delete git source",
Short: "Delete a GitRepository source",
Long: "The delete source git command deletes the given GitRepository from the cluster.",
RunE: deleteSourceGitCmdRun,
}
@@ -55,12 +72,12 @@ func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
}
logAction("deleting source %s in %s namespace", name, namespace)
logger.Actionf("deleting source %s in %s namespace", name, namespace)
err = kubeClient.Delete(ctx, &git)
if err != nil {
return err
}
logSuccess("source deleted")
logger.Successf("source deleted")
return nil
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var exportCmd = &cobra.Command{
Use: "export",
Short: "Export commands",
Short: "Export resources in YAML format",
Long: "The export sub-commands export resources in YAML format.",
}
var (

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -15,11 +31,12 @@ import (
var exportKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Export kustomization in YAML format",
Example: ` # Export all kustomizations
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
# Export a kustomization
# Export a Kustomization
export kustomization my-app > kustomization.yaml
`,
RunE: exportKsCmdRun,
@@ -50,7 +67,7 @@ func exportKsCmdRun(cmd *cobra.Command, args []string) error {
}
if len(list.Items) == 0 {
logFailure("no kustomizations found in %s namespace", namespace)
logger.Failuref("no kustomizations found in %s namespace", namespace)
return nil
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var exportSourceCmd = &cobra.Command{
Use: "source",
Short: "Export source commands",
Short: "Export sources",
Long: "The export source sub-commands export sources in YAML format.",
}
var (

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -15,11 +31,12 @@ import (
var exportSourceGitCmd = &cobra.Command{
Use: "git [name]",
Short: "Export git sources in YAML format",
Example: ` # Export all git sources
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
# Export a git source including the SSH keys or basic auth credentials
# Export a GitRepository source including the SSH key pair or basic auth credentials
export source git my-private-repo --with-credentials > source.yaml
`,
RunE: exportSourceGitCmdRun,
@@ -50,7 +67,7 @@ func exportSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
if len(list.Items) == 0 {
logFailure("no source found in %s namespace", namespace)
logger.Failuref("no source found in %s namespace", namespace)
return nil
}
@@ -109,16 +126,16 @@ func exportGit(source sourcev1.GitRepository) error {
return nil
}
func exportGitCredentials(ctx context.Context, kubeClinet client.Client, source sourcev1.GitRepository) error {
func exportGitCredentials(ctx context.Context, kubeClient client.Client, source sourcev1.GitRepository) error {
if source.Spec.SecretRef != nil {
namespacedName := types.NamespacedName{
Namespace: source.Namespace,
Name: source.Spec.SecretRef.Name,
}
var cred corev1.Secret
err := kubeClinet.Get(ctx, namespacedName, &cred)
err := kubeClient.Get(ctx, namespacedName, &cred)
if err != nil {
return fmt.Errorf("get secret failed: %w", err)
return fmt.Errorf("failed to retrieve secret %s, error: %w", namespacedName.Name, err)
}
exported := corev1.Secret{

130
cmd/tk/flags.go Normal file
View 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 (
"crypto/elliptic"
"fmt"
"sort"
"strconv"
"strings"
)
var supportedPublicKeyAlgorithms = []string{"rsa", "ecdsa", "ed25519"}
type PublicKeyAlgorithm string
func (a *PublicKeyAlgorithm) String() string {
return string(*a)
}
func (a *PublicKeyAlgorithm) Set(str string) error {
if strings.TrimSpace(str) == "" {
return fmt.Errorf("no public key algorithm given, must be one of: %s",
strings.Join(supportedPublicKeyAlgorithms, ", "))
}
for _, v := range supportedPublicKeyAlgorithms {
if str == v {
*a = PublicKeyAlgorithm(str)
return nil
}
}
return fmt.Errorf("unsupported public key algorithm '%s', must be one of: %s",
str, strings.Join(supportedPublicKeyAlgorithms, ", "))
}
func (a *PublicKeyAlgorithm) Type() string {
return "publicKeyAlgorithm"
}
func (a *PublicKeyAlgorithm) Description() string {
return fmt.Sprintf("SSH public key algorithm (%s)", strings.Join(supportedPublicKeyAlgorithms, ", "))
}
var defaultRSAKeyBits = 2048
type RSAKeyBits int
func (b *RSAKeyBits) String() string {
return strconv.Itoa(int(*b))
}
func (b *RSAKeyBits) Set(str string) error {
if strings.TrimSpace(str) == "" {
*b = RSAKeyBits(defaultRSAKeyBits)
return nil
}
bits, err := strconv.Atoi(str)
if err != nil {
return err
}
if bits%8 != 0 {
return fmt.Errorf("RSA key bit size should be a multiples of 8")
}
*b = RSAKeyBits(bits)
return nil
}
func (b *RSAKeyBits) Type() string {
return "rsaKeyBits"
}
func (b *RSAKeyBits) Description() string {
return "SSH RSA public key bit size (multiplies of 8)"
}
type ECDSACurve struct {
elliptic.Curve
}
var supportedECDSACurves = map[string]elliptic.Curve{
"p256": elliptic.P256(),
"p384": elliptic.P384(),
"p521": elliptic.P521(),
}
func (c *ECDSACurve) String() string {
if c.Curve == nil {
return ""
}
return strings.ToLower(strings.Replace(c.Curve.Params().Name, "-", "", 1))
}
func (c *ECDSACurve) Set(str string) error {
if v, ok := supportedECDSACurves[str]; ok {
*c = ECDSACurve{v}
return nil
}
return fmt.Errorf("unsupported curve '%s', should be one of: %s", str, strings.Join(ecdsaCurves(), ", "))
}
func (c *ECDSACurve) Type() string {
return "ecdsaCurve"
}
func (c *ECDSACurve) Description() string {
return fmt.Sprintf("SSH ECDSA public key curve (%s)", strings.Join(ecdsaCurves(), ", "))
}
func ecdsaCurves() []string {
keys := make([]string, 0, len(supportedECDSACurves))
for k := range supportedECDSACurves {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var getCmd = &cobra.Command{
Use: "get",
Short: "Get commands",
Short: "Get sources and resources",
Long: "The get sub-commands print the statuses of sources and resources.",
}
func init() {

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -12,10 +28,9 @@ import (
var getKsCmd = &cobra.Command{
Use: "kustomizations",
Aliases: []string{"ks"},
Short: "Get kustomizations status",
Long: `
The get kustomizations command prints the status of the resources.`,
RunE: getKsCmdRun,
Short: "Get Kustomization source statuses",
Long: "The get kustomizations command prints the statuses of the resources.",
RunE: getKsCmdRun,
}
func init() {
@@ -38,29 +53,33 @@ func getKsCmdRun(cmd *cobra.Command, args []string) error {
}
if len(list.Items) == 0 {
logFailure("no kustomizations found in %s namespace", namespace)
logger.Failuref("no kustomizations found in %s namespace", namespace)
return nil
}
for _, kustomization := range list.Items {
if kustomization.Spec.Suspend {
logSuccess("%s is suspended", kustomization.GetName())
logger.Successf("%s is suspended", kustomization.GetName())
continue
}
isInitialized := false
for _, condition := range kustomization.Status.Conditions {
if condition.Type == kustomizev1.ReadyCondition {
if condition.Status != corev1.ConditionFalse {
logSuccess("%s last applied revision %s", kustomization.GetName(), kustomization.Status.LastAppliedRevision)
if kustomization.Status.LastAppliedRevision != "" {
logger.Successf("%s last applied revision %s", kustomization.GetName(), kustomization.Status.LastAppliedRevision)
} else {
logger.Successf("%s reconciling", kustomization.GetName())
}
} else {
logFailure("%s %s", kustomization.GetName(), condition.Message)
logger.Failuref("%s %s", kustomization.GetName(), condition.Message)
}
isInitialized = true
break
}
}
if !isInitialized {
logFailure("%s is not ready", kustomization.GetName())
logger.Failuref("%s is not ready", kustomization.GetName())
}
}
return nil

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var getSourceCmd = &cobra.Command{
Use: "sources",
Short: "Get sources commands",
Short: "Get source statuses",
Long: "The get source sub-commands print the statuses of the sources.",
}
func init() {

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -11,10 +27,9 @@ import (
var getSourceGitCmd = &cobra.Command{
Use: "git",
Short: "Get git sources status",
Long: `
The get sources command prints the status of the git resources.`,
RunE: getSourceGitCmdRun,
Short: "Get GitRepository source statuses",
Long: "The get sources git command prints the status of the GitRepository sources.",
RunE: getSourceGitCmdRun,
}
func init() {
@@ -37,7 +52,7 @@ func getSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
if len(list.Items) == 0 {
logFailure("no sources found in %s namespace", namespace)
logger.Failuref("no sources found in %s namespace", namespace)
return nil
}
@@ -46,16 +61,16 @@ func getSourceGitCmdRun(cmd *cobra.Command, args []string) error {
for _, condition := range source.Status.Conditions {
if condition.Type == sourcev1.ReadyCondition {
if condition.Status != corev1.ConditionFalse {
logSuccess("%s last fetched revision %s", source.GetName(), source.Status.Artifact.Revision)
logger.Successf("%s last fetched revision: %s", source.GetName(), source.Status.Artifact.Revision)
} else {
logFailure("%s %s", source.GetName(), condition.Message)
logger.Failuref("%s %s", source.GetName(), condition.Message)
}
isInitialized = true
break
}
}
if !isInitialized {
logFailure("%s is not ready", source.GetName())
logger.Failuref("%s is not ready", source.GetName())
}
}
return nil

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -8,6 +24,7 @@ import (
"path"
"path/filepath"
"strings"
"time"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/api/filesys"
@@ -17,32 +34,40 @@ import (
var installCmd = &cobra.Command{
Use: "install",
Short: "Install the toolkit components",
Long: `
The install command deploys the toolkit components in the specified namespace.
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=master --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=0.0.1 --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 (
installExport bool
installDryRun bool
installManifestsPath string
installVersion string
installComponents []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",
installCmd.Flags().StringVarP(&installVersion, "version", "v", defaultVersion,
"toolkit tag or branch")
installCmd.Flags().StringSliceVar(&installComponents, "components", defaultComponents,
"list of components, accepts comma-separated values")
installCmd.Flags().StringVarP(&installManifestsPath, "manifests", "", "",
"path to the manifest directory, dev only")
rootCmd.AddCommand(installCmd)
@@ -66,9 +91,11 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
}
defer os.RemoveAll(tmpDir)
logGenerate("generating manifests")
if !installExport {
logger.Generatef("generating manifests")
}
if kustomizePath == "" {
err = genInstallManifests(installVersion, namespace, components, tmpDir)
err = genInstallManifests(installVersion, namespace, installComponents, tmpDir)
if err != nil {
return fmt.Errorf("install failed: %w", err)
}
@@ -86,11 +113,17 @@ 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.Print(yaml)
fmt.Println("---")
return nil
}
}
logSuccess("manifests build completed")
logger.Successf("manifests build completed")
logAction("installing components in %s namespace", namespace)
logger.Actionf("installing components in %s namespace", namespace)
applyOutput := ModeStderrOS
if verbose {
applyOutput = ModeOS
@@ -106,24 +139,24 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
}
if installDryRun {
logSuccess("install dry-run finished")
logger.Successf("install dry-run finished")
return nil
} else {
logSuccess("install completed")
logger.Successf("install completed")
}
logWaiting("verifying installation")
for _, deployment := range components {
logger.Waitingf("verifying installation")
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 {
return fmt.Errorf("install failed")
} else {
logSuccess("%s ready", deployment)
logger.Successf("%s ready", deployment)
}
}
logSuccess("install finished")
logger.Successf("install finished")
return nil
}

View File

@@ -1,23 +1,41 @@
/*
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 "fmt"
func logAction(format string, a ...interface{}) {
type printLogger struct{}
func (l printLogger) Actionf(format string, a ...interface{}) {
fmt.Println(``, fmt.Sprintf(format, a...))
}
func logGenerate(format string, a ...interface{}) {
func (l printLogger) Generatef(format string, a ...interface{}) {
fmt.Println(``, fmt.Sprintf(format, a...))
}
func logWaiting(format string, a ...interface{}) {
func (l printLogger) Waitingf(format string, a ...interface{}) {
fmt.Println(``, fmt.Sprintf(format, a...))
}
func logSuccess(format string, a ...interface{}) {
func (l printLogger) Successf(format string, a ...interface{}) {
fmt.Println(``, fmt.Sprintf(format, a...))
}
func logFailure(format string, a ...interface{}) {
func (l printLogger) Failuref(format string, a ...interface{}) {
fmt.Println(``, fmt.Sprintf(format, a...))
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -9,6 +25,8 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
_ "k8s.io/client-go/plugin/pkg/client/auth"
tklog "github.com/fluxcd/toolkit/pkg/log"
)
var VERSION = "0.0.0-dev.0"
@@ -32,16 +50,16 @@ var rootCmd = &cobra.Command{
--branch=master \
--interval=3m
# List git sources and their status
# List GitRepository sources and their status
tk get sources git
# Trigger a git sync
# Trigger a GitRepository source sync
tk sync source git webapp-latest
# Export git sources in YAML format
# Export GitRepository sources in YAML format
tk export source git --all > sources.yaml
# Create a kustomization for deploying a series of microservices
# Create a Kustomization for deploying a series of microservices
tk create kustomization webapp-dev \
--source=webapp-latest \
--path="./deploy/webapp/" \
@@ -52,22 +70,22 @@ var rootCmd = &cobra.Command{
--health-check="Deployment/frontend.webapp" \
--health-check-timeout=2m
# Trigger a git sync and apply changes if any
tk sync kustomization webapp-dev --with-source
# Trigger a git sync of the Kustomization's source and apply changes
tk reconcile kustomization webapp-dev --with-source
# Suspend a kustomization reconciliation
# Suspend a Kustomization reconciliation
tk suspend kustomization webapp-dev
# Export kustomizations in YAML format
# Export Kustomizations in YAML format
tk export kustomization --all > kustomizations.yaml
# Resume a kustomization reconciliation
# Resume a Kustomization reconciliation
tk resume kustomization webapp-dev
# Delete a kustomization
# Delete a Kustomization
tk delete kustomization webapp-dev
# Delete a git source
# Delete a GitRepository source
tk delete source git webapp-latest
# Uninstall the toolkit and delete CRDs
@@ -80,21 +98,24 @@ var (
namespace string
timeout time.Duration
verbose bool
components []string
utils Utils
pollInterval = 2 * time.Second
pollInterval = 2 * time.Second
logger tklog.Logger = printLogger{}
)
var (
defaultComponents = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
defaultVersion = "master"
defaultNamespace = "gitops-system"
)
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"},
"list of components, accepts comma-separated values")
}
func main() {
@@ -102,7 +123,7 @@ func main() {
generateDocs()
kubeconfigFlag()
if err := rootCmd.Execute(); err != nil {
logFailure("%v", err)
logger.Failuref("%v", err)
os.Exit(1)
}
}
@@ -115,6 +136,10 @@ func kubeconfigFlag() {
rootCmd.PersistentFlags().StringVarP(&kubeconfig, "kubeconfig", "", "",
"absolute path to the kubeconfig file")
}
if len(os.Getenv("KUBECONFIG")) > 0 {
kubeconfig = os.Getenv("KUBECONFIG")
}
}
func generateDocs() {
@@ -122,6 +147,7 @@ func generateDocs() {
if len(args) > 0 && args[0] == "docgen" {
rootCmd.PersistentFlags().StringVarP(&kubeconfig, "kubeconfig", "", "~/.kube/config",
"path to the kubeconfig file")
rootCmd.DisableAutoGenTag = true
err := doc.GenMarkdownTree(rootCmd, "./docs/cmd")
if err != nil {
log.Fatal(err)

31
cmd/tk/reconcile.go Normal file
View File

@@ -0,0 +1,31 @@
/*
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 (
"github.com/spf13/cobra"
)
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(reconcileCmd)
}

View 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
}
}

View File

@@ -0,0 +1,119 @@
/*
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"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
)
var reconcileKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Reconcile a Kustomization resource",
Long: `
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
tk reconcile kustomization podinfo
# Trigger a sync of the Kustomization's source and apply changes
tk reconcile kustomization podinfo --with-source
`,
RunE: reconcileKsCmdRun,
}
var (
syncKsWithSource bool
)
func init() {
reconcileKsCmd.Flags().BoolVar(&syncKsWithSource, "with-source", false, "reconcile kustomization source")
reconcileCmd.AddCommand(reconcileKsCmd)
}
func reconcileKsCmdRun(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("kustomization 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 kustomization kustomizev1.Kustomization
err = kubeClient.Get(ctx, namespacedName, &kustomization)
if err != nil {
return err
}
if syncKsWithSource {
err := syncSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
if err != nil {
return err
}
} else {
logger.Actionf("annotating kustomization %s in %s namespace", name, namespace)
if kustomization.Annotations == nil {
kustomization.Annotations = map[string]string{
kustomizev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
kustomization.Annotations[kustomizev1.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
}
if err := kubeClient.Update(ctx, &kustomization); err != nil {
return err
}
logger.Successf("kustomization annotated")
}
logger.Waitingf("waiting for kustomization reconciliation")
if err := wait.PollImmediate(pollInterval, timeout,
isKustomizationReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
logger.Successf("kustomization reconciliation completed")
err = kubeClient.Get(ctx, namespacedName, &kustomization)
if err != nil {
return err
}
if kustomization.Status.LastAppliedRevision != "" {
logger.Successf("reconciled revision %s", kustomization.Status.LastAppliedRevision)
} else {
return fmt.Errorf("kustomization sync failed")
}
return nil
}

View File

@@ -0,0 +1,31 @@
/*
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 (
"github.com/spf13/cobra"
)
var reconcileSourceCmd = &cobra.Command{
Use: "source",
Short: "Reconcile sources",
Long: "The reconcile source sub-commands trigger a reconciliation of sources.",
}
func init() {
reconcileCmd.AddCommand(reconcileSourceCmd)
}

View File

@@ -0,0 +1,100 @@
/*
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"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"time"
)
var reconcileSourceGitCmd = &cobra.Command{
Use: "git [name]",
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
tk reconcile source git podinfo
`,
RunE: syncSourceGitCmdRun,
}
func init() {
reconcileSourceCmd.AddCommand(reconcileSourceGitCmd)
}
func syncSourceGitCmdRun(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 gitRepository sourcev1.GitRepository
err = kubeClient.Get(ctx, namespacedName, &gitRepository)
if err != nil {
return err
}
if gitRepository.Annotations == nil {
gitRepository.Annotations = map[string]string{
sourcev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
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 reconciliation")
if err := wait.PollImmediate(pollInterval, timeout,
isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
logger.Successf("git reconciliation completed")
err = kubeClient.Get(ctx, namespacedName, &gitRepository)
if err != nil {
return err
}
if gitRepository.Status.Artifact != nil {
logger.Successf("fetched revision %s", gitRepository.Status.Artifact.Revision)
} else {
return fmt.Errorf("git reconciliation failed, artifact not found")
}
return nil
}

View 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 helm repo update 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
}
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var resumeCmd = &cobra.Command{
Use: "resume",
Short: "Resume commands",
Short: "Resume suspended resources",
Long: "The resume sub-commands resume a suspended resource.",
}
func init() {

View File

@@ -0,0 +1,126 @@
/*
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.`,
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
}
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -16,9 +32,10 @@ import (
var resumeKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Resume kustomization",
Long: "The resume command marks a previously suspended Kustomization resource for reconciliation and waits for it to finish the apply.",
RunE: resumeKsCmdRun,
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.`,
RunE: resumeKsCmdRun,
}
func init() {
@@ -49,20 +66,20 @@ func resumeKsCmdRun(cmd *cobra.Command, args []string) error {
return err
}
logAction("resuming kustomization %s in %s namespace", name, namespace)
logger.Actionf("resuming kustomization %s in %s namespace", name, namespace)
kustomization.Spec.Suspend = false
if err := kubeClient.Update(ctx, &kustomization); err != nil {
return err
}
logSuccess("kustomization resumed")
logger.Successf("kustomization resumed")
logWaiting("waiting for kustomization sync")
logger.Waitingf("waiting for kustomization sync")
if err := wait.PollImmediate(pollInterval, timeout,
isKustomizationResumed(ctx, kubeClient, name, namespace)); err != nil {
return err
}
logSuccess("kustomization sync completed")
logger.Successf("kustomization sync completed")
err = kubeClient.Get(ctx, namespacedName, &kustomization)
if err != nil {
@@ -70,7 +87,7 @@ func resumeKsCmdRun(cmd *cobra.Command, args []string) error {
}
if kustomization.Status.LastAppliedRevision != "" {
logSuccess("applied revision %s", kustomization.Status.LastAppliedRevision)
logger.Successf("applied revision %s", kustomization.Status.LastAppliedRevision)
} else {
return fmt.Errorf("kustomization sync failed")
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -6,7 +22,8 @@ import (
var suspendCmd = &cobra.Command{
Use: "suspend",
Short: "Suspend commands",
Short: "Suspend resources",
Long: "The suspend sub-commands suspend the reconciliation of a resource.",
}
func init() {

View File

@@ -0,0 +1,73 @@
/*
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.",
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
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -11,7 +27,7 @@ import (
var suspendKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Suspend kustomization",
Short: "Suspend reconciliation of Kustomization",
Long: "The suspend command disables the reconciliation of a Kustomization resource.",
RunE: suspendKsCmdRun,
}
@@ -44,12 +60,12 @@ func suspendKsCmdRun(cmd *cobra.Command, args []string) error {
return err
}
logAction("suspending kustomization %s in %s namespace", name, namespace)
logger.Actionf("suspending kustomization %s in %s namespace", name, namespace)
kustomization.Spec.Suspend = true
if err := kubeClient.Update(ctx, &kustomization); err != nil {
return err
}
logSuccess("kustomization suspended")
logger.Successf("kustomization suspended")
return nil
}

View File

@@ -1,14 +0,0 @@
package main
import (
"github.com/spf13/cobra"
)
var syncCmd = &cobra.Command{
Use: "sync",
Short: "Synchronize commands",
}
func init() {
rootCmd.AddCommand(syncCmd)
}

View File

@@ -1,103 +0,0 @@
package main
import (
"context"
"fmt"
"time"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
)
var syncKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Synchronize kustomization",
Long: `
The sync 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
# Trigger a git sync of the kustomization source and apply changes
sync kustomization podinfo --with-source
`,
RunE: syncKsCmdRun,
}
var (
syncKsWithSource bool
)
func init() {
syncKsCmd.Flags().BoolVar(&syncKsWithSource, "with-source", false, "synchronize kustomization source")
syncCmd.AddCommand(syncKsCmd)
}
func syncKsCmdRun(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("kustomization 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 kustomization kustomizev1.Kustomization
err = kubeClient.Get(ctx, namespacedName, &kustomization)
if err != nil {
return err
}
if syncKsWithSource {
err := syncSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
if err != nil {
return err
}
} else {
logAction("annotating kustomization %s in %s namespace", name, namespace)
if kustomization.Annotations == nil {
kustomization.Annotations = map[string]string{
kustomizev1.SyncAtAnnotation: time.Now().String(),
}
} else {
kustomization.Annotations[kustomizev1.SyncAtAnnotation] = time.Now().String()
}
if err := kubeClient.Update(ctx, &kustomization); err != nil {
return err
}
logSuccess("kustomization annotated")
}
logWaiting("waiting for kustomization sync")
if err := wait.PollImmediate(pollInterval, timeout,
isKustomizationReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
logSuccess("kustomization sync completed")
err = kubeClient.Get(ctx, namespacedName, &kustomization)
if err != nil {
return err
}
if kustomization.Status.LastAppliedRevision != "" {
logSuccess("applied revision %s", kustomization.Status.LastAppliedRevision)
} else {
return fmt.Errorf("kustomization sync failed")
}
return nil
}

View File

@@ -1,14 +0,0 @@
package main
import (
"github.com/spf13/cobra"
)
var syncSourceCmd = &cobra.Command{
Use: "source",
Short: "Synchronize source commands",
}
func init() {
syncCmd.AddCommand(syncSourceCmd)
}

View File

@@ -1,85 +0,0 @@
package main
import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"time"
)
var syncSourceGitCmd = &cobra.Command{
Use: "git [name]",
Short: "Synchronize git source",
Long: `
The sync 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
`,
RunE: syncSourceGitCmdRun,
}
func init() {
syncSourceCmd.AddCommand(syncSourceGitCmd)
}
func syncSourceGitCmdRun(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,
}
logAction("annotating source %s in %s namespace", name, namespace)
var gitRepository sourcev1.GitRepository
err = kubeClient.Get(ctx, namespacedName, &gitRepository)
if err != nil {
return err
}
if gitRepository.Annotations == nil {
gitRepository.Annotations = map[string]string{
sourcev1.SyncAtAnnotation: time.Now().String(),
}
} else {
gitRepository.Annotations[sourcev1.SyncAtAnnotation] = time.Now().String()
}
if err := kubeClient.Update(ctx, &gitRepository); err != nil {
return err
}
logSuccess("source annotated")
logWaiting("waiting for git sync")
if err := wait.PollImmediate(pollInterval, timeout,
isGitRepositoryReady(ctx, kubeClient, name, namespace)); err != nil {
return err
}
logSuccess("git sync completed")
err = kubeClient.Get(ctx, namespacedName, &gitRepository)
if err != nil {
return err
}
if gitRepository.Status.Artifact != nil {
logSuccess("fetched revision %s", gitRepository.Status.Artifact.Revision)
} else {
return fmt.Errorf("git sync failed, artifact not found")
}
return nil
}

View File

@@ -1,8 +1,25 @@
/*
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/manifoldco/promptui"
"github.com/spf13/cobra"
@@ -11,9 +28,7 @@ import (
var uninstallCmd = &cobra.Command{
Use: "uninstall",
Short: "Uninstall the toolkit components",
Long: `
The uninstall command removes the namespace, cluster roles,
cluster role bindings and CRDs.`,
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
@@ -24,12 +39,15 @@ cluster role bindings and CRDs.`,
}
var (
uninstallCRDs bool
uninstallDryRun bool
uninstallSilent bool
uninstallCRDs bool
uninstallKustomizations bool
uninstallDryRun bool
uninstallSilent bool
)
func init() {
uninstallCmd.Flags().BoolVarP(&uninstallKustomizations, "kustomizations", "", false,
"removes all Kustomizations previously installed")
uninstallCmd.Flags().BoolVarP(&uninstallCRDs, "crds", "", false,
"removes all CRDs previously installed")
uninstallCmd.Flags().BoolVarP(&uninstallDryRun, "dry-run", "", false,
@@ -57,18 +75,32 @@ 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")
}
// 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"
if uninstallCRDs {
kinds += ",crds"
}
logAction("uninstalling components")
logger.Actionf("uninstalling components")
command := fmt.Sprintf("kubectl delete %s -l app.kubernetes.io/instance=%s --timeout=%s %s",
kinds, namespace, timeout.String(), dryRun)
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
return fmt.Errorf("uninstall failed")
}
logSuccess("uninstall finished")
logger.Successf("uninstall finished")
return nil
}

View File

@@ -1,3 +1,19 @@
/*
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 (
@@ -95,7 +111,7 @@ func (*Utils) execTemplate(obj interface{}, tmpl, filename string) error {
func (*Utils) kubeClient(config string) (client.Client, error) {
cfg, err := clientcmd.BuildConfigFromFlags("", config)
if err != nil {
return nil, fmt.Errorf("kubernetes client initialization failed: %w", err)
return nil, fmt.Errorf("Kubernetes client initialization failed: %w", err)
}
scheme := runtime.NewScheme()
@@ -107,8 +123,23 @@ func (*Utils) kubeClient(config string) (client.Client, error) {
Scheme: scheme,
})
if err != nil {
return nil, fmt.Errorf("kubernetes client initialization failed: %w", err)
return nil, fmt.Errorf("Kubernetes client initialization failed: %w", err)
}
return kubeClient, nil
}
func (*Utils) writeFile(content, filename string) error {
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
_, err = io.WriteString(file, content)
if err != nil {
return err
}
return file.Sync()
}

22
docs/_files/flux-icon.svg Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 56.3 (81716) - https://sketch.com -->
<title>flux-icon</title>
<desc>Created with Sketch.</desc>
<g id="flux-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" transform="translate(11.000000, 2.000000)">
<path d="M0.803134615,15.7791346 C-0.246288462,15.0966346 -0.246288462,13.5602885 0.803134615,12.8783654 L20.1819808,0.279519231 C20.7554423,-0.0931730769 21.4944808,-0.0931730769 22.0679423,0.279519231 L41.4473654,12.8783654 C42.4967885,13.5602885 42.4967885,15.0966346 41.4473654,15.7791346 L22.0679423,28.3779808 C21.4944808,28.7506731 20.7554423,28.7506731 20.1819808,28.3779808 L0.803134615,15.7791346 Z" id="Fill-1" fill="#326CE5"></path>
<path d="M24.1851346,18.0023077 L25.5293654,18.0023077 C26.3145577,18.0023077 26.8055192,17.1525 26.4126346,16.4728846 L22.0084038,8.84423077 C21.6160962,8.16461538 20.63475,8.16461538 20.2418654,8.84423077 L15.8376346,16.4728846 C15.4453269,17.1525 15.9357115,18.0023077 16.7209038,18.0023077 L18.0657115,18.0023077 C18.6287885,18.0023077 19.0851346,18.4592308 19.0851346,19.0223077 L19.0851346,27.7298077 L19.9874423,28.3165385 C20.6791731,28.7665385 21.5710962,28.7665385 22.2628269,28.3165385 L23.1651346,27.7298077 L23.1651346,19.0223077 C23.1651346,18.4592308 23.6214808,18.0023077 24.1851346,18.0023077" id="Fill-3" fill="#C1D2F7"></path>
<path d="M27.8390769,34.8375577 L23.1648462,31.7989038 L23.1648462,33.2389038 C24.6902308,33.8919808 26.2588846,34.4008269 27.8390769,34.8375577" id="Fill-5" fill="#326CE5"></path>
<path d="M23.1650769,35.8280192 L23.1650769,37.8495577 C24.7095,38.3209038 26.2723846,38.7080192 27.8191154,39.0893654 C32.8706538,40.3349423 37.6418077,41.5107115 41.4783462,45.3478269 C41.6733462,45.54225 41.8562308,45.7407115 42.0373846,45.93975 C42.4308462,45.1880192 42.2335385,44.1957115 41.4466154,43.6845577 L33.8560385,38.7489808 C32.0133462,38.1409038 30.1360385,37.6759038 28.2806538,37.2189808 C26.5308462,36.7874423 24.8196923,36.3570577 23.1650769,35.8280192" id="Fill-7" fill="#326CE5"></path>
<path d="M19.08525,34.1699423 C18.4304423,33.8318654 17.7854423,33.4689808 17.1629423,33.0489808 L15.4269808,34.1774423 C16.5975577,35.0382115 17.8235192,35.7362885 19.08525,36.3212885 L19.08525,34.1699423 Z" id="Fill-9" fill="#326CE5"></path>
<path d="M24.8941731,40.6051154 C24.3137885,40.4620385 23.7374423,40.3195385 23.1651346,40.1735769 L23.1651346,42.1605 C23.5885962,42.2666538 24.0114808,42.3722308 24.4326346,42.4760769 C29.4841731,43.7210769 34.2553269,44.8968462 38.0924423,48.7339615 C38.0987885,48.7408846 38.1045577,48.7472308 38.1114808,48.7541538 L39.75225,47.6868462 C39.6524423,47.5824231 39.5584038,47.4751154 39.4545577,47.3718462 C35.2384038,43.1551154 29.9791731,41.8587692 24.8941731,40.6051154" id="Fill-11" fill="#326CE5"></path>
<path d="M19.08525,38.9907115 C16.8900577,38.2389808 14.8096731,37.2714808 12.9115962,35.8124423 L11.2119808,36.9178269 C13.6287115,38.9110962 16.3194808,40.1203269 19.08525,41.0168654 L19.08525,38.9907115 Z" id="Fill-13" fill="#326CE5"></path>
<path d="M19.08525,43.3809808 C15.3069808,42.3909808 11.7537115,41.18175 8.71794231,38.5388654 L7.04717308,39.6252115 C10.6125577,42.9102115 14.8540962,44.2832885 19.08525,45.3707885 L19.08525,43.3809808 Z" id="Fill-15" fill="#326CE5"></path>
<path d="M23.1650769,46.3935 C27.1175769,47.4140769 30.8341154,48.6342692 33.9823846,51.4381154 L35.6439231,50.3581154 C31.9654615,46.9000385 27.5514231,45.5194615 23.1650769,44.4048462 L23.1650769,46.3935 Z" id="Fill-17" fill="#326CE5"></path>
<path d="M4.57875,41.2299231 L2.92990385,42.3018462 C2.98759615,42.3612692 3.04009615,42.423 3.09951923,42.4818462 C7.31625,46.6985769 12.5743269,47.9949231 17.6599038,49.2485769 C22.0641346,50.3337692 26.2543269,51.3687692 29.7989423,54.1581923 L31.4893269,53.0591538 C27.4958654,49.6968462 22.7385577,48.5158846 18.1214423,47.3781923 C13.1206731,46.1453077 8.39567308,44.9758846 4.57875,41.2299231" id="Fill-19" fill="#326CE5"></path>
<path d="M1.07555769,44.5060962 C0.883442308,44.3139808 0.702865385,44.1184038 0.524019231,43.9216731 C-0.227711538,44.6745577 -0.139442308,45.9726346 0.80325,46.5853269 L6.50959615,50.2955192 C9.03536538,51.3409038 11.6765192,51.9945577 14.2738269,52.6349423 C18.3284423,53.6341731 22.2019038,54.5924423 25.5578654,56.9157115 L27.2834423,55.7930192 C23.4676731,52.9245577 19.0403654,51.8255192 14.7347885,50.7639808 C9.68382692,49.5189808 4.91267308,48.3432115 1.07555769,44.5060962" id="Fill-21" fill="#326CE5"></path>
<path d="M19.6441154,58.8342692 C20.0243077,59.0188846 20.3998846,59.2133077 20.7691154,59.4221538 C21.2093077,59.5150385 21.6771923,59.4383077 22.0683462,59.1838846 L23.0260385,58.5613846 C19.9493077,56.5035 16.5287308,55.461 13.1196923,54.5927308 L19.6441154,58.8342692 Z" id="Fill-23" fill="#326CE5"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

24
docs/_static/custom.css vendored Normal file
View File

@@ -0,0 +1,24 @@
@import url("https://fonts.googleapis.com/css?family=Montserrat&display=swap");
body {
font-family: "Montserrat", sans-serif;
}
.md-logo {
width: 40px;
height: 40px;
padding-bottom: 2px;
padding-top: 2px;
}
.md-logo img {
width: 40px;
height: 40px;
}
.md-header, .md-footer-nav {
background-image: linear-gradient(45deg, rgb(0, 150, 225) 0%, rgb(27, 141, 226) 24%, rgb(42, 125, 227) 53%, rgb(53, 112, 227) 78%, rgb(53, 112, 227) 100%);
}
.md-header-nav__title {
font-size: .85rem;
}

View File

@@ -21,16 +21,16 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
--branch=master \
--interval=3m
# List git sources and their status
# List GitRepository sources and their status
tk get sources git
# Trigger a git sync
# Trigger a GitRepository source sync
tk sync source git webapp-latest
# Export git sources in YAML format
# Export GitRepository sources in YAML format
tk export source git --all > sources.yaml
# Create a kustomization for deploying a series of microservices
# Create a Kustomization for deploying a series of microservices
tk create kustomization webapp-dev \
--source=webapp-latest \
--path="./deploy/webapp/" \
@@ -41,22 +41,22 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
--health-check="Deployment/frontend.webapp" \
--health-check-timeout=2m
# Trigger a git sync and apply changes if any
tk sync kustomization webapp-dev --with-source
# Trigger a git sync of the Kustomization's source and apply changes
tk reconcile kustomization webapp-dev --with-source
# Suspend a kustomization reconciliation
# Suspend a Kustomization reconciliation
tk suspend kustomization webapp-dev
# Export kustomizations in YAML format
# Export Kustomizations in YAML format
tk export kustomization --all > kustomizations.yaml
# Resume a kustomization reconciliation
# Resume a Kustomization reconciliation
tk resume kustomization webapp-dev
# Delete a kustomization
# Delete a Kustomization
tk delete kustomization webapp-dev
# Delete a git source
# Delete a GitRepository source
tk delete source git webapp-latest
# Uninstall the toolkit and delete CRDs
@@ -67,26 +67,25 @@ 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])
-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
* [tk bootstrap](tk_bootstrap.md) - Bootstrap toolkit components
* [tk check](tk_check.md) - Check requirements and installation
* [tk completion](tk_completion.md) - Generates bash completion scripts
* [tk create](tk_create.md) - Create commands
* [tk delete](tk_delete.md) - Delete commands
* [tk export](tk_export.md) - Export commands
* [tk get](tk_get.md) - Get commands
* [tk create](tk_create.md) - Create or update sources and resources
* [tk delete](tk_delete.md) - Delete sources and resources
* [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 resume](tk_resume.md) - Resume commands
* [tk suspend](tk_suspend.md) - Suspend commands
* [tk sync](tk_sync.md) - Synchronize commands
* [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 uninstall](tk_uninstall.md) - Uninstall the toolkit components
###### Auto generated by spf13/cobra on 5-May-2020

31
docs/cmd/tk_bootstrap.md Normal file
View File

@@ -0,0 +1,31 @@
## tk bootstrap
Bootstrap toolkit components
### Synopsis
The bootstrap sub-commands bootstrap the toolkit components on the targeted Git provider.
### Options
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
-h, --help help for bootstrap
-v, --version string toolkit tag or branch (default "master")
```
### 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 bootstrap github](tk_bootstrap_github.md) - Bootstrap toolkit components in a GitHub repository
* [tk bootstrap gitlab](tk_bootstrap_gitlab.md) - Bootstrap toolkit components in a GitLab repository

View File

@@ -0,0 +1,68 @@
## tk bootstrap github
Bootstrap toolkit components in a GitHub repository
### Synopsis
The bootstrap github command creates the GitHub repository if it doesn't exists and
commits the toolkit components manifests to the master branch.
Then it configures the target cluster to synchronize with the repository.
If the toolkit components are present on the cluster,
the bootstrap command will perform an upgrade if needed.
```
tk bootstrap github [flags]
```
### Examples
```
# Create a GitHub personal access token and export it as an env var
export GITHUB_TOKEN=<my-token>
# Run bootstrap for a private repo owned by a GitHub organization
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>
# Run bootstrap for a repository path
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
# Run bootstrap for a private repo hosted on GitHub Enterprise
bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
```
### Options
```
-h, --help help for github
--hostname string GitHub hostname (default "github.com")
--interval duration sync interval (default 1m0s)
--owner string GitHub user or organization name
--path string repository path, when specified the cluster sync will be scoped to this path
--personal is personal repository
--private is private repository (default true)
--repository string GitHub repository name
--team stringArray GitHub team to be given maintainer access
```
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-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
-v, --version string toolkit tag or branch (default "master")
```
### SEE ALSO
* [tk bootstrap](tk_bootstrap.md) - Bootstrap toolkit components

View File

@@ -0,0 +1,64 @@
## tk bootstrap gitlab
Bootstrap toolkit components in a GitLab repository
### Synopsis
The bootstrap gitlab command creates the GitLab repository if it doesn't exists and
commits the toolkit components manifests to the master branch.
Then it configures the target cluster to synchronize with the repository.
If the toolkit components are present on the cluster,
the bootstrap command will perform an upgrade if needed.
```
tk bootstrap gitlab [flags]
```
### Examples
```
# Create a GitLab API token and export it as an env var
export GITLAB_TOKEN=<my-token>
# Run bootstrap for a private repo owned by a GitLab group
bootstrap gitlab --owner=<group> --repository=<repo name>
# Run bootstrap for a repository path
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
# Run bootstrap for a private repo hosted on a GitLab server
bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
```
### Options
```
-h, --help help for gitlab
--hostname string GitLab hostname (default "gitlab.com")
--interval duration sync interval (default 1m0s)
--owner string GitLab user or group name
--path string repository path, when specified the cluster sync will be scoped to this path
--personal is personal repository
--private is private repository (default true)
--repository string GitLab repository name
```
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-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
-v, --version string toolkit tag or branch (default "master")
```
### SEE ALSO
* [tk bootstrap](tk_bootstrap.md) - Bootstrap toolkit components

View File

@@ -4,7 +4,6 @@ Check requirements and installation
### Synopsis
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.
@@ -16,32 +15,31 @@ 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])
--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
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -33,15 +33,13 @@ 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])
--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
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,14 +1,15 @@
## tk create
Create commands
Create or update sources and resources
### Synopsis
Create commands
The create sub-commands generate sources and resources.
### Options
```
--export export in YAML format to stdout
-h, --help help for create
--interval duration source sync interval (default 1m0s)
```
@@ -16,17 +17,15 @@ Create commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 kustomization](tk_create_kustomization.md) - Create or update a kustomization resource
* [tk create source](tk_create_source.md) - Create source commands
* [tk create kustomization](tk_create_kustomization.md) - Create or update a Kustomization resource
* [tk create source](tk_create_source.md) - Create or update sources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,12 +1,10 @@
## tk create kustomization
Create or update a kustomization resource
Create or update a Kustomization resource
### Synopsis
The kustomization source command generates a kustomization.kustomize.fluxcd.io resource for a given GitRepository source.
API spec: https://github.com/fluxcd/kustomize-controller/tree/master/docs/spec/v1alpha1
The kustomization source create command generates a Kustomize resource for a given GitRepository source.
```
tk create kustomization [name] [flags]
@@ -15,7 +13,7 @@ tk create kustomization [name] [flags]
### Examples
```
# Create a kustomization from a source at a given path
# Create a Kustomization resource from a source at a given path
create kustomization contour \
--source=contour \
--path="./examples/contour/" \
@@ -26,7 +24,7 @@ tk create kustomization [name] [flags]
--health-check="DaemonSet/envoy.projectcontour" \
--health-check-timeout=3m
# Create a kustomization that depends on the previous one
# Create a Kustomization resource that depends on the previous one
create kustomization webapp \
--depends-on=contour \
--source=webapp \
@@ -35,7 +33,7 @@ tk create kustomization [name] [flags]
--interval=5m \
--validate=client
# Create a kustomization that runs under a service account
# Create a Kustomization resource that runs under a service account
create kustomization webapp \
--source=webapp \
--path="./deploy/overlays/staging" \
@@ -50,11 +48,11 @@ tk create kustomization [name] [flags]
### Options
```
--depends-on stringArray kustomization that must be ready before this kustomization can be applied
--depends-on stringArray Kustomization that must be ready before this Kustomization can be applied
--health-check stringArray workload to be included in the health assessment, in the format '<kind>/<name>.<namespace>'
--health-check-timeout duration timeout of health checking operations (default 2m0s)
-h, --help help for kustomization
--path string path to the directory containing the kustomization file (default "./")
--path string path to the directory containing the Kustomization file (default "./")
--prune enable garbage collection
--sa-name string service account name
--sa-namespace string service account namespace
@@ -65,16 +63,15 @@ tk create kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--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 commands
* [tk create](tk_create.md) - Create or update sources and resources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk create source
Create source commands
Create or update sources
### Synopsis
Create source commands
The create source sub-commands generate sources.
### Options
@@ -15,17 +15,16 @@ Create source commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--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 commands
* [tk create source git](tk_create_source_git.md) - Create or update a git source
* [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
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,11 +1,11 @@
## tk create source git
Create or update a git source
Create or update a GitRepository source
### Synopsis
The create source command generates a GitRepository resource and waits for it to sync.
The create source git command generates a GitRepository resource and waits for it to sync.
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.
@@ -31,11 +31,19 @@ tk create source git [name] [flags]
--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 a source from a Git repository using SSH authentication
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 \
--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 \
--url=https://github.com/stefanprodan/podinfo \
@@ -47,28 +55,30 @@ tk create source git [name] [flags]
### Options
```
--branch string git branch (default "master")
-h, --help help for git
-p, --password string basic authentication password
--tag string git tag
--tag-semver string git tag semver range
--url string git address, e.g. ssh://git@host/org/repository
-u, --username string basic authentication username
--branch string git branch (default "master")
-h, --help help for git
-p, --password string basic authentication password
--ssh-ecdsa-curve ecdsaCurve SSH ECDSA public key curve (p256, p384, p521) (default p384)
--ssh-key-algorithm publicKeyAlgorithm SSH public key algorithm (rsa, ecdsa, ed25519) (default rsa)
--ssh-rsa-bits rsaKeyBits SSH RSA public key bit size (multiplies of 8) (default 2048)
--tag string git tag
--tag-semver string git tag semver range
--url string git address, e.g. ssh://git@host/org/repository
-u, --username string basic authentication username
```
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--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 source](tk_create_source.md) - Create source commands
* [tk create source](tk_create_source.md) - Create or update sources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk delete
Delete commands
Delete sources and resources
### Synopsis
Delete commands
The delete sub-commands delete sources and resources.
### Options
@@ -16,17 +16,15 @@ Delete commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 kustomization](tk_delete_kustomization.md) - Delete kustomization
* [tk delete source](tk_delete_source.md) - Delete sources commands
* [tk delete kustomization](tk_delete_kustomization.md) - Delete a Kustomization resource
* [tk delete source](tk_delete_source.md) - Delete sources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk delete kustomization
Delete kustomization
Delete a Kustomization resource
### Synopsis
Delete kustomization
The delete kustomization command deletes the given Kustomization from the cluster.
```
tk delete kustomization [name] [flags]
@@ -19,16 +19,14 @@ tk delete kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 commands
* [tk delete](tk_delete.md) - Delete sources and resources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk delete source
Delete sources commands
Delete sources
### Synopsis
Delete sources commands
The delete source sub-commands delete sources.
### Options
@@ -15,17 +15,15 @@ Delete sources commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 commands
* [tk delete source git](tk_delete_source_git.md) - Delete git source
* [tk delete](tk_delete.md) - Delete sources and resources
* [tk delete source git](tk_delete_source_git.md) - Delete a GitRepository source
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk delete source git
Delete git source
Delete a GitRepository source
### Synopsis
Delete git source
The delete source git command deletes the given GitRepository from the cluster.
```
tk delete source git [name] [flags]
@@ -19,16 +19,14 @@ 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])
--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 source](tk_delete_source.md) - Delete sources commands
* [tk delete source](tk_delete_source.md) - Delete sources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk export
Export commands
Export resources in YAML format
### Synopsis
Export commands
The export sub-commands export resources in YAML format.
### Options
@@ -16,17 +16,15 @@ Export commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 kustomization](tk_export_kustomization.md) - Export kustomization in YAML format
* [tk export source](tk_export_source.md) - Export source commands
* [tk export kustomization](tk_export_kustomization.md) - Export Kustomization resources in YAML format
* [tk export source](tk_export_source.md) - Export sources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk export kustomization
Export kustomization in YAML format
Export Kustomization resources in YAML format
### Synopsis
Export kustomization in YAML format
The export kustomization command exports one or all Kustomization resources in YAML format.
```
tk export kustomization [name] [flags]
@@ -13,10 +13,10 @@ tk export kustomization [name] [flags]
### Examples
```
# Export all kustomizations
# Export all Kustomization resources
export kustomization --all > kustomizations.yaml
# Export a kustomization
# Export a Kustomization
export kustomization my-app > kustomization.yaml
```
@@ -30,16 +30,14 @@ 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])
--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 commands
* [tk export](tk_export.md) - Export resources in YAML format
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk export source
Export source commands
Export sources
### Synopsis
Export source commands
The export source sub-commands export sources in YAML format.
### Options
@@ -16,17 +16,15 @@ Export source commands
### Options inherited from parent commands
```
--all select all resources
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 commands
* [tk export source git](tk_export_source_git.md) - Export git sources in YAML format
* [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
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk export source git
Export git sources in YAML format
Export GitRepository sources in YAML format
### Synopsis
Export git sources in YAML format
The export source git command exports on or all GitRepository sources in YAML format.
```
tk export source git [name] [flags]
@@ -13,10 +13,10 @@ tk export source git [name] [flags]
### Examples
```
# Export all git sources
# Export all GitRepository sources
export source git --all > sources.yaml
# Export a git source including the SSH keys or basic auth credentials
# Export a GitRepository source including the SSH key pair or basic auth credentials
export source git my-private-repo --with-credentials > source.yaml
```
@@ -30,17 +30,15 @@ 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])
--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
* [tk export source](tk_export_source.md) - Export source commands
* [tk export source](tk_export_source.md) - Export sources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk get
Get commands
Get sources and resources
### Synopsis
Get commands
The get sub-commands print the statuses of sources and resources.
### Options
@@ -15,17 +15,15 @@ Get commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 kustomizations status
* [tk get sources](tk_get_sources.md) - Get sources commands
* [tk get kustomizations](tk_get_kustomizations.md) - Get Kustomization source statuses
* [tk get sources](tk_get_sources.md) - Get source statuses
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,11 +1,10 @@
## tk get kustomizations
Get kustomizations status
Get Kustomization source statuses
### Synopsis
The get kustomizations command prints the status of the resources.
The get kustomizations command prints the statuses of the resources.
```
tk get kustomizations [flags]
@@ -20,15 +19,13 @@ tk get kustomizations [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 commands
* [tk get](tk_get.md) - Get sources and resources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk get sources
Get sources commands
Get source statuses
### Synopsis
Get sources commands
The get source sub-commands print the statuses of the sources.
### Options
@@ -15,16 +15,14 @@ Get sources commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 commands
* [tk get sources git](tk_get_sources_git.md) - Get git sources status
* [tk get](tk_get.md) - Get sources and resources
* [tk get sources git](tk_get_sources_git.md) - Get GitRepository source statuses
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,11 +1,10 @@
## tk get sources git
Get git sources status
Get GitRepository source statuses
### Synopsis
The get sources command prints the status of the git resources.
The get sources git command prints the status of the GitRepository sources.
```
tk get sources git [flags]
@@ -20,15 +19,13 @@ tk get sources git [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 sources](tk_get_sources.md) - Get sources commands
* [tk get sources](tk_get_sources.md) - Get source statuses
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -4,7 +4,6 @@ Install the toolkit components
### Synopsis
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.
@@ -16,37 +15,40 @@ tk install [flags]
```
# Install the latest version in the gitops-systems namespace
install --version=master --namespace=gitops-systems
tk install --version=master --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=0.0.1 --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
--manifests string path to the manifest directory, dev only
-v, --version string toolkit tag or branch (default "master")
```
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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
###### Auto generated by spf13/cobra on 5-May-2020

30
docs/cmd/tk_reconcile.md Normal file
View 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

View 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

View 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

View 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

View 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

View 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 helm repo update 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

View File

@@ -1,10 +1,10 @@
## tk resume
Resume commands
Resume suspended resources
### Synopsis
Resume commands
The resume sub-commands resume a suspended resource.
### Options
@@ -15,16 +15,15 @@ Resume commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 kustomization](tk_resume_kustomization.md) - Resume kustomization
* [tk resume helmrelease](tk_resume_helmrelease.md) - Resume a suspended HelmRelease
* [tk resume kustomization](tk_resume_kustomization.md) - Resume a suspended Kustomization
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -0,0 +1,32 @@
## 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]
```
### 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

View File

@@ -1,10 +1,11 @@
## tk resume kustomization
Resume kustomization
Resume a suspended Kustomization
### Synopsis
The resume command marks a previously suspended Kustomization resource for reconciliation and waits for it to finish the apply.
The resume command marks a previously suspended Kustomization resource for reconciliation and waits for it to
finish the apply.
```
tk resume kustomization [name] [flags]
@@ -19,15 +20,13 @@ tk resume kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 resume](tk_resume.md) - Resume commands
* [tk resume](tk_resume.md) - Resume suspended resources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,10 +1,10 @@
## tk suspend
Suspend commands
Suspend resources
### Synopsis
Suspend commands
The suspend sub-commands suspend the reconciliation of a resource.
### Options
@@ -15,16 +15,15 @@ Suspend commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 kustomization](tk_suspend_kustomization.md) - Suspend kustomization
* [tk suspend helmrelease](tk_suspend_helmrelease.md) - Suspend reconciliation of HelmRelease
* [tk suspend kustomization](tk_suspend_kustomization.md) - Suspend reconciliation of Kustomization
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -0,0 +1,31 @@
## tk suspend helmrelease
Suspend reconciliation of HelmRelease
### Synopsis
The suspend command disables the reconciliation of a HelmRelease resource.
```
tk suspend helmrelease [name] [flags]
```
### 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

View File

@@ -1,6 +1,6 @@
## tk suspend kustomization
Suspend kustomization
Suspend reconciliation of Kustomization
### Synopsis
@@ -19,15 +19,13 @@ tk suspend kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-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 suspend](tk_suspend.md) - Suspend commands
* [tk suspend](tk_suspend.md) - Suspend resources
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,31 +0,0 @@
## tk sync
Synchronize commands
### Synopsis
Synchronize commands
### 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])
--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 kustomization
* [tk sync source](tk_sync_source.md) - Synchronize source commands
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,46 +0,0 @@
## tk sync kustomization
Synchronize kustomization
### 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 git sync of the kustomization 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])
--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 commands
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,30 +0,0 @@
## tk sync source
Synchronize source commands
### Synopsis
Synchronize source commands
### 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])
--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 commands
* [tk sync source git](tk_sync_source_git.md) - Synchronize git source
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -1,42 +0,0 @@
## tk sync source git
Synchronize git 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])
--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 source commands
###### Auto generated by spf13/cobra on 5-May-2020

View File

@@ -4,9 +4,7 @@ Uninstall the toolkit components
### Synopsis
The uninstall command removes the namespace, cluster roles,
cluster role bindings and CRDs.
The uninstall command removes the namespace, cluster roles, cluster role bindings and CRDs from the cluster.
```
tk uninstall [flags]
@@ -26,24 +24,23 @@ tk uninstall [flags]
### Options
```
--crds removes all CRDs previously installed
--dry-run only print the object that would be deleted
-h, --help help for uninstall
-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
--kustomizations removes all Kustomizations previously installed
-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])
--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
###### Auto generated by spf13/cobra on 5-May-2020

View 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.
![](../../_files/helm-controller.png)
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)

View File

@@ -0,0 +1,23 @@
# Kustomize Controller
The kustomize-controller is a Kubernetes operator,
specialized in running continuous delivery pipelines for infrastructure and
workloads defined with Kubernetes manifests and assembled with Kustomize.
![](../../_files/kustomize-controller.png)
Features:
- Reconciles the cluster state from multiple sources (provided by source-controller)
- Generates manifests with Kustomize (from plain Kubernetes yamls or Kustomize overlays)
- Validates manifests against Kubernetes API
- Impersonates service accounts (multi-tenancy RBAC)
- Health assessment of the deployed workloads
- Runs pipelines in a specific order (depends-on relationship)
- Prunes objects removed from source (garbage collection)
- Reports cluster state changes (alerting provided by notification-controller)
Links:
- Source code [fluxcd/kustomize-controller](https://github.com/fluxcd/kustomize-controller)
- Specification [docs](https://github.com/fluxcd/kustomize-controller/tree/master/docs/spec)

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