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

Compare commits

...

65 Commits

Author SHA1 Message Date
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
105 changed files with 2460 additions and 1820 deletions

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

@@ -0,0 +1,31 @@
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: |
cp install/tk.sh docs/install.sh
curl https://raw.githubusercontent.com/fluxcd/source-controller/master/docs/api/source.md > docs/components/source/api.md
curl https://raw.githubusercontent.com/fluxcd/source-controller/master/docs/spec/v1alpha1/gitrepositories.md > docs/components/source/gitrepositories.md
curl https://raw.githubusercontent.com/fluxcd/source-controller/master/docs/spec/v1alpha1/helmrepositories.md > docs/components/source/helmrepositories.md
curl https://raw.githubusercontent.com/fluxcd/kustomize-controller/master/docs/api/kustomize.md > docs/components/kustomize/api.md
curl https://raw.githubusercontent.com/fluxcd/kustomize-controller/master/docs/spec/v1alpha1/kustomization.md > docs/components/kustomize/kustomization.md
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/api/notification.md > docs/components/notification/api.md
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/spec/v1alpha1/event.md > docs/components/notification/event.md
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/spec/v1alpha1/alert.md > docs/components/notification/alert.md
curl https://raw.githubusercontent.com/fluxcd/notification-controller/master/docs/spec/v1alpha1/provider.md > docs/components/notification/provider.md
- name: Deploy docs
uses: mhausenblas/mkdocs-deploy-gh-pages@master
env:
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

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

@@ -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/).

View File

@@ -1,20 +1,250 @@
/*
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 commands",
Short: "Bootstrap toolkit components",
Long: "The bootstrap sub-commands bootstrap the toolkit components on the targeted Git provider.",
}
var (
bootstrapVersion string
)
const (
bootstrapBranch = "master"
bootstrapInstallManifest = "toolkit-components.yaml"
bootstrapSourceManifest = "toolkit-source.yaml"
bootstrapKustomizationManifest = "toolkit-kustomization.yaml"
)
func init() {
bootstrapCmd.PersistentFlags().StringVar(&bootstrapVersion, "version", "master", "toolkit tag or branch")
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, components, 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")
emptyAPIGroup := ""
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: corev1.TypedLocalObjectReference{
APIGroup: &emptyAPIGroup,
Kind: "GitRepository",
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
}

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 (
@@ -7,34 +23,19 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"sigs.k8s.io/yaml"
"strings"
"time"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/google/go-github/v32/github"
"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"
"github.com/fluxcd/pkg/git"
)
var bootstrapGitHubCmd = &cobra.Command{
Use: "github",
Short: "Bootstrap GitHub repository",
Long: `
The bootstrap command creates the GitHub repository if it doesn't exists and
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 configure the target cluster to synchronize with the repository.
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
@@ -43,6 +44,9 @@ the bootstrap command will perform an upgrade if needed.`,
# 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
@@ -63,39 +67,40 @@ var (
ghPrivate bool
ghHostname string
ghPath string
ghTeams []string
)
const (
ghTokenName = "GITHUB_TOKEN"
ghBranch = "master"
ghInstallManifest = "toolkit-components.yaml"
ghSourceManifest = "toolkit-source.yaml"
ghKustomizationManifest = "toolkit-kustomization.yaml"
ghDefaultHostname = "github.com"
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", ghDefaultHostname, "GitHub hostname")
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(ghTokenName)
ghToken := os.Getenv(git.GitHubTokenName)
if ghToken == "" {
return fmt.Errorf("%s environment variable not found", ghTokenName)
return fmt.Errorf("%s environment variable not found", git.GitHubTokenName)
}
ghURL := fmt.Sprintf("https://%s/%s/%s", ghHostname, ghOwner, ghRepository)
sshURL := fmt.Sprintf("ssh://git@%s/%s/%s", ghHostname, ghOwner, ghRepository)
if ghOwner == "" || ghRepository == "" {
return fmt.Errorf("owner and repository are required")
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)
@@ -113,470 +118,123 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
defer cancel()
// create GitHub repository if doesn't exists
logAction("connecting to %s", ghHostname)
if err := createGitHubRepository(ctx, ghHostname, ghOwner, ghRepository, ghToken, ghPrivate, ghPersonal); err != nil {
return err
}
// clone repository and checkout the master branch
repo, err := checkoutGitHubRepository(ctx, ghURL, ghBranch, ghToken, tmpDir)
logger.Actionf("connecting to %s", ghHostname)
changed, err := provider.CreateRepository(ctx, repository)
if err != nil {
return err
}
logSuccess("repository cloned")
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
logGenerate("generating manifests")
manifest, err := generateGitHubInstall(ghPath, namespace, tmpDir)
logger.Generatef("generating manifests")
manifest, err := generateInstallManifests(ghPath, namespace, tmpDir)
if err != nil {
return err
}
// stage install manifests
changed, err := commitGitHubManifests(repo, ghPath, namespace)
changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests")
if err != nil {
return err
}
// push install manifests
if changed {
if err := pushGitHubRepository(ctx, repo, ghToken); err != nil {
if err := repository.Push(ctx); err != nil {
return err
}
logSuccess("components manifests pushed")
logger.Successf("components manifests pushed")
} else {
logSuccess("components are up to date")
logger.Successf("components are up to date")
}
// determine if repo synchronization is working
isInstall := shouldInstallGitHub(ctx, kubeClient, namespace)
isInstall := shouldInstallManifests(ctx, kubeClient, namespace)
if isInstall {
// apply install manifests
logAction("installing components in %s namespace", namespace)
command := fmt.Sprintf("kubectl apply -f %s", manifest)
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
return fmt.Errorf("install failed")
}
logSuccess("install completed")
// check installation
logWaiting("verifying installation")
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")
} else {
logSuccess("%s ready", deployment)
}
logger.Actionf("installing components in %s namespace", namespace)
if err := applyInstallManifests(ctx, manifest, components); err != nil {
return err
}
logger.Successf("install completed")
}
// setup SSH deploy key
if shouldCreateGitHubDeployKey(ctx, kubeClient, namespace) {
logAction("configuring deploy key")
u, err := url.Parse(sshURL)
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 := generateGitHubDeployKey(ctx, kubeClient, u, namespace)
key, err := generateDeployKey(ctx, kubeClient, u, namespace)
if err != nil {
return fmt.Errorf("generating deploy key failed: %w", err)
}
if err := createGitHubDeployKey(ctx, key, ghHostname, ghOwner, ghRepository, ghPath, ghToken); err != nil {
return 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")
}
logSuccess("deploy key configured")
}
// configure repo synchronization
if isInstall {
// generate source and kustomization manifests
logAction("generating sync manifests")
if err := generateGitHubKustomization(sshURL, namespace, namespace, ghPath, tmpDir, ghInterval); err != nil {
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, ghPath, tmpDir, ghInterval); err != nil {
return err
}
// stage manifests
changed, err = commitGitHubManifests(repo, ghPath, namespace)
if err != nil {
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests"); err != nil {
return err
}
// push manifests
if changed {
if err := pushGitHubRepository(ctx, repo, ghToken); err != nil {
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("sync manifests pushed")
}
logSuccess("sync manifests pushed")
// apply manifests and waiting for sync
logAction("applying sync manifests")
if err := applyGitHubKustomization(ctx, kubeClient, namespace, namespace, ghPath, tmpDir); err != nil {
logger.Actionf("applying sync manifests")
if err := applySyncManifests(ctx, kubeClient, namespace, namespace, ghPath, tmpDir); err != nil {
return err
}
}
logSuccess("bootstrap finished")
return nil
}
func makeGitHubClient(hostname, token string) (*github.Client, error) {
auth := github.BasicAuthTransport{
Username: "git",
Password: token,
}
gh := github.NewClient(auth.Client())
if hostname != ghDefaultHostname {
baseURL := fmt.Sprintf("https://%s/api/v3/", hostname)
uploadURL := fmt.Sprintf("https://%s/api/uploads/", hostname)
if g, err := github.NewEnterpriseClient(baseURL, uploadURL, auth.Client()); err == nil {
gh = g
} else {
return nil, fmt.Errorf("github client error: %w", err)
}
}
return gh, nil
}
func createGitHubRepository(ctx context.Context, hostname, owner, name, token string, isPrivate, isPersonal bool) error {
gh, err := makeGitHubClient(hostname, token)
if err != nil {
return err
}
org := ""
if !isPersonal {
org = owner
}
if _, _, err := gh.Repositories.Get(ctx, org, name); err == nil {
return nil
}
autoInit := true
_, _, err = gh.Repositories.Create(ctx, org, &github.Repository{
AutoInit: &autoInit,
Name: &name,
Private: &isPrivate,
})
if err != nil {
if !strings.Contains(err.Error(), "name already exists on this account") {
return fmt.Errorf("github create repository error: %w", err)
}
} else {
logSuccess("repository created")
}
return nil
}
func checkoutGitHubRepository(ctx context.Context, url, branch, token, path string) (*git.Repository, error) {
auth := &http.BasicAuth{
Username: "git",
Password: token,
}
repo, err := git.PlainCloneContext(ctx, path, false, &git.CloneOptions{
URL: url,
Auth: auth,
RemoteName: git.DefaultRemoteName,
ReferenceName: plumbing.NewBranchReferenceName(branch),
SingleBranch: true,
NoCheckout: false,
Progress: nil,
Tags: git.NoTags,
})
if err != nil {
return nil, fmt.Errorf("git clone error: %w", err)
}
_, err = repo.Head()
if err != nil {
return nil, fmt.Errorf("git resolve HEAD error: %w", err)
}
return repo, nil
}
func generateGitHubInstall(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, components, 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, ghInstallManifest)
if err := buildKustomization(tkDir, manifest); err != nil {
return "", fmt.Errorf("build kustomization failed: %w", err)
}
return manifest, nil
}
func commitGitHubManifests(repo *git.Repository, targetPath, namespace string) (bool, error) {
w, err := repo.Worktree()
if err != nil {
return false, err
}
_, err = w.Add(path.Join(targetPath, namespace))
if err != nil {
return false, err
}
status, err := w.Status()
if err != nil {
return false, err
}
if !status.IsClean() {
if _, err := w.Commit("Add manifests", &git.CommitOptions{
Author: &object.Signature{
Name: "tk",
Email: "tk@users.noreply.github.com",
When: time.Now(),
},
}); err != nil {
return false, err
}
return true, nil
}
return false, nil
}
func pushGitHubRepository(ctx context.Context, repo *git.Repository, token string) error {
auth := &http.BasicAuth{
Username: "git",
Password: token,
}
err := repo.PushContext(ctx, &git.PushOptions{
Auth: auth,
Progress: nil,
})
if err != nil {
return fmt.Errorf("git push error: %w", err)
}
return nil
}
func generateGitHubKustomization(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, ghSourceManifest)); err != nil {
return err
}
gvk = kustomizev1.GroupVersion.WithKind("Kustomization")
emptyAPIGroup := ""
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: "./" + strings.TrimPrefix("./", targetPath),
Prune: true,
SourceRef: corev1.TypedLocalObjectReference{
APIGroup: &emptyAPIGroup,
Kind: "GitRepository",
Name: name,
},
},
}
ksData, err := yaml.Marshal(kustomization)
if err != nil {
return err
}
if err := utils.writeFile(string(ksData), filepath.Join(tmpDir, targetPath, namespace, ghKustomizationManifest)); err != nil {
return err
}
return nil
}
func applyGitHubKustomization(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
}
logWaiting("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 shouldInstallGitHub(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 shouldCreateGitHubDeployKey(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 generateGitHubDeployKey(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
}
func createGitHubDeployKey(ctx context.Context, key, hostname, owner, repository, targetPath, token string) error {
gh, err := makeGitHubClient(hostname, token)
if err != nil {
return err
}
keyName := "tk"
if targetPath != "" {
keyName = fmt.Sprintf("tk-%s", targetPath)
}
// list deploy keys
keys, resp, err := gh.Repositories.ListKeys(ctx, owner, repository, nil)
if err != nil {
return fmt.Errorf("github list deploy keys error: %w", err)
}
if resp.StatusCode >= 300 {
return fmt.Errorf("github list deploy keys failed with status code: %s", resp.Status)
}
// check if the key exists
shouldCreateKey := true
var existingKey *github.Key
for _, k := range keys {
if k.Title != nil && k.Key != nil && *k.Title == keyName {
if *k.Key != key {
existingKey = k
} else {
shouldCreateKey = false
}
break
}
}
// delete existing key if the value differs
if existingKey != nil {
resp, err := gh.Repositories.DeleteKey(ctx, owner, repository, *existingKey.ID)
if err != nil {
return fmt.Errorf("github delete deploy key error: %w", err)
}
if resp.StatusCode >= 300 {
return fmt.Errorf("github delete deploy key failed with status code: %s", resp.Status)
}
}
// create key
if shouldCreateKey {
isReadOnly := true
_, _, err = gh.Repositories.CreateKey(ctx, owner, repository, &github.Key{
Title: &keyName,
Key: &key,
ReadOnly: &isReadOnly,
})
if err != nil {
return fmt.Errorf("github create deploy key error: %w", 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, components); 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,8 +32,7 @@ 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
@@ -43,7 +58,7 @@ 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 !kubectlCheck(ctx, ">=1.18.0") {
@@ -58,83 +73,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 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
}
@@ -147,10 +162,10 @@ func componentsCheck() bool {
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,7 +24,8 @@ 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 (
@@ -18,6 +35,6 @@ var (
func init() {
createCmd.PersistentFlags().DurationVarP(&interval, "interval", "", time.Minute, "source sync interval")
createCmd.PersistentFlags().BoolVar(&export, "export", false, "export in yaml format to stdout")
createCmd.PersistentFlags().BoolVar(&export, "export", false, "export in YAML format to stdout")
rootCmd.AddCommand(createCmd)
}

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 (
@@ -21,11 +37,9 @@ import (
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/" \
@@ -36,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 \
@@ -45,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" \
@@ -72,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)
@@ -108,7 +122,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
}
if !export {
logGenerate("generating kustomization")
logger.Generatef("generating kustomization")
}
emptyAPIGroup := ""
@@ -178,18 +192,18 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
return exportKs(kustomization)
}
logAction("applying 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,
@@ -201,7 +215,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")
}
@@ -222,7 +236,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
}
}
@@ -234,7 +248,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,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 (
@@ -19,14 +35,14 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/toolkit/pkg/ssh"
"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
@@ -150,7 +166,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
withAuth := false
// TODO(hidde): move all auth prep to separate func?
if u.Scheme == "ssh" {
logAction("generating deploy key pair")
logger.Actionf("generating deploy key pair")
pair, err := generateKeyPair(ctx)
if err != nil {
return err
@@ -165,15 +181,15 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("aborting")
}
logAction("collecting preferred public key from SSH server")
logger.Actionf("collecting preferred public key from SSH server")
hostKey, err := scanHostKey(ctx, u)
if err != nil {
return err
}
logSuccess("collected public key from SSH server:")
logger.Successf("collected public key from SSH server:")
fmt.Printf("%s", hostKey)
logAction("applying secret with keys")
logger.Actionf("applying secret with keys")
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -190,7 +206,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
withAuth = true
} else if sourceGitUsername != "" && sourceGitPassword != "" {
logAction("applying secret with basic auth credentials")
logger.Actionf("applying secret with basic auth credentials")
secret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -208,10 +224,10 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
if withAuth {
logSuccess("authentication configured")
logger.Successf("authentication configured")
}
logGenerate("generating source")
logger.Generatef("generating source")
if withAuth {
gitRepository.Spec.SecretRef = &corev1.LocalObjectReference{
@@ -219,18 +235,18 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
}
}
logAction("applying source")
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,
@@ -242,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")
}
@@ -252,7 +268,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
func generateKeyPair(ctx context.Context) (*ssh.KeyPair, error) {
var keyGen ssh.KeyPairGenerator
switch sourceGitKeyAlgorithm.String() {
switch algorithm := sourceGitKeyAlgorithm.String(); algorithm {
case "rsa":
keyGen = ssh.NewRSAGenerator(int(sourceGitRSABits))
case "ecdsa":
@@ -260,11 +276,11 @@ func generateKeyPair(ctx context.Context) (*ssh.KeyPair, error) {
case "ed25519":
keyGen = ssh.NewEd25519Generator()
default:
return nil, fmt.Errorf("unsupported public key algorithm '%s'", sourceGitKeyAlgorithm.String())
return nil, fmt.Errorf("unsupported public key algorithm: %s", algorithm)
}
pair, err := keyGen.Generate()
if err != nil {
return nil, fmt.Errorf("key pair generation failed: %w", err)
return nil, fmt.Errorf("key pair generation failed, error: %w", err)
}
return pair, nil
}
@@ -276,7 +292,7 @@ func scanHostKey(ctx context.Context, url *url.URL) ([]byte, error) {
}
hostKey, err := ssh.ScanHostKey(host, 30*time.Second)
if err != nil {
return nil, fmt.Errorf("SSH key scan for host '%s' failed: %w", host, err)
return nil, fmt.Errorf("SSH key scan for host %s failed, error: %w", host, err)
}
return hostKey, nil
}
@@ -320,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
}
}
@@ -332,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{

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 (
"crypto/elliptic"
"fmt"
"sort"
"strconv"
"strings"
)
@@ -108,5 +125,6 @@ func ecdsaCurves() []string {
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 (
@@ -17,8 +33,7 @@ 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
@@ -66,7 +81,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
}
defer os.RemoveAll(tmpDir)
logGenerate("generating manifests")
logger.Generatef("generating manifests")
if kustomizePath == "" {
err = genInstallManifests(installVersion, namespace, components, tmpDir)
if err != nil {
@@ -88,9 +103,9 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
fmt.Print(yaml)
}
}
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 +121,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")
logger.Waitingf("verifying installation")
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, 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
# Trigger a git sync of the Kustomization's source and apply changes
tk sync 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
@@ -82,7 +100,8 @@ var (
verbose bool
components []string
utils Utils
pollInterval = 2 * time.Second
pollInterval = 2 * time.Second
logger tklog.Logger = printLogger{}
)
func init() {
@@ -93,7 +112,7 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false,
"print generated objects")
rootCmd.PersistentFlags().StringSliceVar(&components, "components",
[]string{"source-controller", "kustomize-controller"},
[]string{"source-controller", "kustomize-controller", "notification-controller"},
"list of components, accepts comma-separated values")
}
@@ -102,7 +121,7 @@ func main() {
generateDocs()
kubeconfigFlag()
if err := rootCmd.Execute(); err != nil {
logFailure("%v", err)
logger.Failuref("%v", err)
os.Exit(1)
}
}
@@ -115,6 +134,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 +145,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)

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

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

@@ -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,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 syncCmd = &cobra.Command{
Use: "sync",
Short: "Synchronize commands",
Short: "Synchronize sources and resources",
Long: "The sync sub-commands trigger a reconciliation 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 (
@@ -14,13 +30,13 @@ import (
var syncKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks"},
Short: "Synchronize kustomization",
Short: "Synchronize a Kustomization resource",
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
Example: ` # Trigger a Kustomization apply outside of the reconciliation interval
sync kustomization podinfo
# Trigger a git sync of the kustomization source and apply changes
# Trigger a sync of the Kustomization's source and apply changes
sync kustomization podinfo --with-source
`,
RunE: syncKsCmdRun,
@@ -67,7 +83,7 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error {
return err
}
} else {
logAction("annotating kustomization %s in %s namespace", name, namespace)
logger.Actionf("annotating kustomization %s in %s namespace", name, namespace)
if kustomization.Annotations == nil {
kustomization.Annotations = map[string]string{
kustomizev1.SyncAtAnnotation: time.Now().String(),
@@ -78,16 +94,16 @@ func syncKsCmdRun(cmd *cobra.Command, args []string) error {
if err := kubeClient.Update(ctx, &kustomization); err != nil {
return err
}
logSuccess("kustomization annotated")
logger.Successf("kustomization annotated")
}
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 sync completed")
logger.Successf("kustomization sync completed")
err = kubeClient.Get(ctx, namespacedName, &kustomization)
if err != nil {
@@ -95,7 +111,7 @@ func syncKsCmdRun(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 syncSourceCmd = &cobra.Command{
Use: "source",
Short: "Synchronize source commands",
Short: "Synchronize sources",
Long: "The sync source sub-commands trigger a reconciliation of 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,9 +28,8 @@ import (
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.`,
Short: "Synchronize a GitRepository 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
`,
@@ -44,7 +59,7 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error {
Name: name,
}
logAction("annotating source %s in %s namespace", name, namespace)
logger.Actionf("annotating source %s in %s namespace", name, namespace)
var gitRepository sourcev1.GitRepository
err = kubeClient.Get(ctx, namespacedName, &gitRepository)
if err != nil {
@@ -61,15 +76,15 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error {
if err := kubeClient.Update(ctx, &gitRepository); err != nil {
return err
}
logSuccess("source annotated")
logger.Successf("source annotated")
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")
err = kubeClient.Get(ctx, namespacedName, &gitRepository)
if err != nil {
@@ -77,7 +92,7 @@ func syncSourceGitCmdRun(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")
}

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,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
@@ -33,7 +47,7 @@ var (
func init() {
uninstallCmd.Flags().BoolVarP(&uninstallKustomizations, "kustomizations", "", false,
"removes all kustomizations previously installed")
"removes all Kustomizations previously installed")
uninstallCmd.Flags().BoolVarP(&uninstallCRDs, "crds", "", false,
"removes all CRDs previously installed")
uninstallCmd.Flags().BoolVarP(&uninstallDryRun, "dry-run", "", false,
@@ -62,7 +76,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
}
if uninstallKustomizations {
logAction("uninstalling kustomizations")
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 {
@@ -71,7 +85,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
// 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
logWaiting("waiting on GC")
logger.Waitingf("waiting on GC")
time.Sleep(30 * time.Second)
}
@@ -80,13 +94,13 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
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,7 +123,7 @@ 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

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: 52 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
# Trigger a git sync of the Kustomization's source and apply changes
tk sync 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,7 +67,7 @@ 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])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
-h, --help help for tk
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
@@ -77,17 +77,16 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.
### SEE ALSO
* [tk bootstrap](tk_bootstrap.md) - Bootstrap commands
* [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 resume](tk_resume.md) - Resume suspended resources
* [tk suspend](tk_suspend.md) - Suspend resources
* [tk sync](tk_sync.md) - Synchronize sources and resources
* [tk uninstall](tk_uninstall.md) - Uninstall the toolkit components
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,10 +1,10 @@
## tk bootstrap
Bootstrap commands
Bootstrap toolkit components
### Synopsis
Bootstrap commands
The bootstrap sub-commands bootstrap the toolkit components on the targeted Git provider.
### Options
@@ -16,7 +16,7 @@ Bootstrap commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -26,6 +26,6 @@ Bootstrap commands
### SEE ALSO
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
* [tk bootstrap github](tk_bootstrap_github.md) - Bootstrap GitHub repository
* [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
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,13 +1,12 @@
## tk bootstrap github
Bootstrap GitHub repository
Bootstrap toolkit components in a GitHub repository
### Synopsis
The bootstrap command creates the GitHub repository if it doesn't exists and
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 configure the target cluster to synchronize with the repository.
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.
@@ -24,6 +23,12 @@ tk bootstrap github [flags]
# 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
@@ -39,15 +44,17 @@ tk bootstrap github [flags]
--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])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -57,6 +64,5 @@ tk bootstrap github [flags]
### SEE ALSO
* [tk bootstrap](tk_bootstrap.md) - Bootstrap commands
* [tk bootstrap](tk_bootstrap.md) - Bootstrap toolkit components
###### Auto generated by spf13/cobra on 9-Jun-2020

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,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects
--version string toolkit tag or branch (default "master")
```
### 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.
@@ -33,7 +32,7 @@ tk check [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -44,4 +43,3 @@ tk check [flags]
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -33,7 +33,7 @@ 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])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -44,4 +44,3 @@ To configure your bash shell to load completions for each session add to your ba
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,15 +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
--export export in YAML format to stdout
-h, --help help for create
--interval duration source sync interval (default 1m0s)
```
@@ -17,7 +17,7 @@ Create commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -27,7 +27,6 @@ Create commands
### 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 9-Jun-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,8 +63,8 @@ tk create kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--export export in yaml format to stdout
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
@@ -76,6 +74,5 @@ tk create kustomization [name] [flags]
### 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 9-Jun-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,8 +15,8 @@ Create source commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--export export in yaml format to stdout
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
@@ -26,7 +26,6 @@ Create source commands
### 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 9-Jun-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.
@@ -58,7 +58,7 @@ tk create source git [name] [flags]
--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 (p521, p256, p384) (default p384)
--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
@@ -70,8 +70,8 @@ tk create source git [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--export export in yaml format to stdout
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
@@ -81,6 +81,5 @@ tk create source git [name] [flags]
### 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 9-Jun-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,7 +16,7 @@ Delete commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -26,7 +26,6 @@ Delete commands
### 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 9-Jun-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,7 +19,7 @@ tk delete kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
-s, --silent delete resource without asking for confirmation
@@ -29,6 +29,5 @@ tk delete kustomization [name] [flags]
### SEE ALSO
* [tk delete](tk_delete.md) - Delete commands
* [tk delete](tk_delete.md) - Delete sources and resources
###### Auto generated by spf13/cobra on 9-Jun-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,7 +15,7 @@ Delete sources commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
-s, --silent delete resource without asking for confirmation
@@ -25,7 +25,6 @@ Delete sources commands
### 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 9-Jun-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,7 +19,7 @@ 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])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
-s, --silent delete resource without asking for confirmation
@@ -29,6 +29,5 @@ tk delete source git [name] [flags]
### 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 9-Jun-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,7 +16,7 @@ Export commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -26,7 +26,6 @@ Export commands
### 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 9-Jun-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
```
@@ -31,7 +31,7 @@ tk export kustomization [name] [flags]
```
--all select all resources
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -40,6 +40,5 @@ tk export kustomization [name] [flags]
### 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 9-Jun-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
@@ -17,7 +17,7 @@ Export source commands
```
--all select all resources
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -26,7 +26,6 @@ Export source commands
### 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 9-Jun-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
```
@@ -31,7 +31,7 @@ tk export source git [name] [flags]
```
--all select all resources
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -41,6 +41,5 @@ tk export source git [name] [flags]
### 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 9-Jun-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,7 +15,7 @@ Get commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -25,7 +25,6 @@ Get commands
### 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 9-Jun-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,7 +19,7 @@ tk get kustomizations [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -29,6 +28,5 @@ tk get kustomizations [flags]
### SEE ALSO
* [tk get](tk_get.md) - Get commands
* [tk get](tk_get.md) - Get sources and resources
###### Auto generated by spf13/cobra on 9-Jun-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,7 +15,7 @@ Get sources commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -24,7 +24,6 @@ Get sources commands
### 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 9-Jun-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,7 +19,7 @@ tk get sources git [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -29,6 +28,5 @@ tk get sources git [flags]
### 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 9-Jun-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.
@@ -38,7 +37,7 @@ tk install [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -49,4 +48,3 @@ tk install [flags]
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
###### Auto generated by spf13/cobra on 9-Jun-2020

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,7 +15,7 @@ Resume commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -25,6 +25,5 @@ Resume commands
### SEE ALSO
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
* [tk resume kustomization](tk_resume_kustomization.md) - Resume kustomization
* [tk resume kustomization](tk_resume_kustomization.md) - Resume a suspended Kustomization
###### Auto generated by spf13/cobra on 9-Jun-2020

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,7 +20,7 @@ tk resume kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -28,6 +29,5 @@ tk resume kustomization [name] [flags]
### SEE ALSO
* [tk resume](tk_resume.md) - Resume commands
* [tk resume](tk_resume.md) - Resume suspended resources
###### Auto generated by spf13/cobra on 9-Jun-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,7 +15,7 @@ Suspend commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -25,6 +25,5 @@ Suspend commands
### SEE ALSO
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
* [tk suspend kustomization](tk_suspend_kustomization.md) - Suspend kustomization
* [tk suspend kustomization](tk_suspend_kustomization.md) - Suspend reconciliation of Kustomization
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,6 +1,6 @@
## tk suspend kustomization
Suspend kustomization
Suspend reconciliation of Kustomization
### Synopsis
@@ -19,7 +19,7 @@ tk suspend kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -28,6 +28,5 @@ tk suspend kustomization [name] [flags]
### SEE ALSO
* [tk suspend](tk_suspend.md) - Suspend commands
* [tk suspend](tk_suspend.md) - Suspend resources
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,10 +1,10 @@
## tk sync
Synchronize commands
Synchronize sources and resources
### Synopsis
Synchronize commands
The sync sub-commands trigger a reconciliation of sources and resources.
### Options
@@ -15,7 +15,7 @@ Synchronize commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -25,7 +25,6 @@ Synchronize commands
### 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
* [tk sync kustomization](tk_sync_kustomization.md) - Synchronize a Kustomization resource
* [tk sync source](tk_sync_source.md) - Synchronize sources
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,6 +1,6 @@
## tk sync kustomization
Synchronize kustomization
Synchronize a Kustomization resource
### Synopsis
@@ -14,10 +14,10 @@ tk sync kustomization [name] [flags]
### Examples
```
# Trigger a kustomization apply outside of the reconciliation interval
# Trigger a Kustomization apply outside of the reconciliation interval
sync kustomization podinfo
# Trigger a git sync of the kustomization source and apply changes
# Trigger a sync of the Kustomization's source and apply changes
sync kustomization podinfo --with-source
```
@@ -32,7 +32,7 @@ tk sync kustomization [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -41,6 +41,5 @@ tk sync kustomization [name] [flags]
### SEE ALSO
* [tk sync](tk_sync.md) - Synchronize commands
* [tk sync](tk_sync.md) - Synchronize sources and resources
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,10 +1,10 @@
## tk sync source
Synchronize source commands
Synchronize sources
### Synopsis
Synchronize source commands
The sync source sub-commands trigger a reconciliation of sources.
### Options
@@ -15,7 +15,7 @@ Synchronize source commands
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -24,7 +24,6 @@ Synchronize source commands
### SEE ALSO
* [tk sync](tk_sync.md) - Synchronize commands
* [tk sync source git](tk_sync_source_git.md) - Synchronize git source
* [tk sync](tk_sync.md) - Synchronize sources and resources
* [tk sync source git](tk_sync_source_git.md) - Synchronize a GitRepository source
###### Auto generated by spf13/cobra on 9-Jun-2020

View File

@@ -1,10 +1,9 @@
## tk sync source git
Synchronize git source
Synchronize a GitRepository source
### Synopsis
The sync source command triggers a reconciliation of a GitRepository resource and waits for it to finish.
```
@@ -28,7 +27,7 @@ tk sync source git [name] [flags]
### Options inherited from parent commands
```
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -37,6 +36,5 @@ tk sync source git [name] [flags]
### SEE ALSO
* [tk sync source](tk_sync_source.md) - Synchronize source commands
* [tk sync source](tk_sync_source.md) - Synchronize sources
###### Auto generated by spf13/cobra on 9-Jun-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,16 +24,17 @@ 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])
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,notification-controller])
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
@@ -46,4 +45,3 @@ tk uninstall [flags]
* [tk](tk.md) - Command line utility for assembling Kubernetes CD pipelines
###### Auto generated by spf13/cobra on 9-Jun-2020

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)

View File

@@ -0,0 +1,16 @@
# Notification Controller
The Notification Controller is a Kubernetes operator,
specialized in dispatching events to external systems such as
Slack, Microsoft Teams, Discord and Rocket chat.
The controller receives events via HTTP and dispatch them to external
webhooks based on event severity and involved objects.
The controller can be configured with Kubernetes custom resources that
define how events are processed and where to dispatch them.
Links:
- Source code [fluxcd/notification-controller](https://github.com/fluxcd/notification-controller)
- Specification [docs](https://github.com/fluxcd/notification-controller/tree/master/docs/spec)

View File

@@ -0,0 +1,24 @@
# Source Controller
The main role of the source management component is to provide a common interface for artifacts acquisition.
The source API defines a set of Kubernetes objects that cluster admins and various automated operators can
interact with to offload the Git and Helm repositories operations to a dedicated controller.
![](../../_files/source-controller.png)
Features:
- Validate source definitions
- Authenticate to sources (SSH, user/password, API token)
- Validate source authenticity (PGP)
- Detect source changes based on update policies (semver)
- Fetch resources on-demand and on-a-schedule
- Package the fetched resources into a well-known format (tar.gz, yaml)
- Make the artifacts addressable by their source identifier (sha, version, ts)
- Make the artifacts available in-cluster to interested 3rd parties
- Notify interested 3rd parties of source changes and availability (status conditions, events, hooks)
Links:
- Source code [fluxcd/source-controller](https://github.com/fluxcd/source-controller)
- Specification [docs](https://github.com/fluxcd/source-controller/tree/master/docs/spec)

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

353
docs/get-started/index.md Normal file
View File

@@ -0,0 +1,353 @@
# Get started with GitOps Toolkit
## Prerequisites
You will need two Kubernetes clusters version 1.14 or newer and kubectl version 1.18.
For a quick local test, you can use [Kubernetes kind](https://kind.sigs.k8s.io/docs/user/quick-start/).
Any other Kubernetes setup will work as well though.
In order to follow the guide you'll need a GitHub account and a
[personal access token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line)
that can create repositories (check all permissions under `repo`).
Export your GitHub personal access token and username:
```sh
export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>
```
## Install the toolkit CLI
To install the latest `tk` release run:
```sh
curl -s https://toolkit.fluxcd.io/install.sh | sudo bash
```
The install script downloads the tk binary to `/usr/local/bin`.
Binaries for macOS and Linux AMD64 are available for download on the
[release page](https://github.com/fluxcd/toolkit/releases).
To configure your shell to load tk completions add to your bash profile:
```sh
# ~/.bashrc or ~/.bash_profile
. <(tk completion)
```
## GitOps workflow
You'll be using a dedicated Git repository e.g. `fleet-infra` to manage one or more Kubernetes clusters.
This guide assumes that you have two clusters, one for staging and one for production.
Using the toolkit CLI you'll do the following:
- configure each cluster to synchronise with a directory inside the fleet repository
- register app sources (git repositories) that contain plain Kubernetes manifests or Kustomize overlays
- configure app deployments on both clusters (pre-releases on staging, semver releases on production)
## Staging bootstrap
Create the staging cluster using Kubernetes kind or set the kubectl context to an existing cluster:
```sh
kind create cluster --name staging
kubectl cluster-info --context kind-staging
```
Verify that your staging cluster satisfies the prerequisites with:
```console
$ tk check --pre
► checking prerequisites
✔ kubectl 1.18.3 >=1.18.0
✔ kubernetes 1.18.2 >=1.14.0
✔ prerequisites checks passed
```
Run the bootstrap command:
```sh
tk bootstrap github \
--owner=$GITHUB_USER \
--repository=fleet-infra \
--path=staging-cluster \
--personal
```
The bootstrap command creates a repository if one doesn't exist and
commits the toolkit components manifests to the master branch at the specified path.
Then it configures the target cluster to synchronize with the specified path inside the repository.
If you wish to create the repository under a GitHub organization:
```sh
tk bootstrap github \
--owner=<organization> \
--repository=<repo-name> \
--team=<team1-slug> \
--team=<team2-slug> \
--path=staging-cluster
```
Example output:
```text
$ tk bootstrap github --owner=gitopsrun --repository=fleet-infra --path=staging-cluster --team=devs
► connecting to github.com
✔ repository created
✔ devs team access granted
✔ repository cloned
✚ generating manifests
✔ components manifests pushed
► installing components in gitops-system namespace
deployment "source-controller" successfully rolled out
deployment "kustomize-controller" successfully rolled out
deployment "notification-controller" successfully rolled out
✔ install completed
► configuring deploy key
✔ deploy key configured
► generating sync manifests
✔ sync manifests pushed
► applying sync manifests
◎ waiting for cluster sync
✔ bootstrap finished
```
If you prefer GitLab, export `GITLAB_TOKEN` env var and use the command [tk bootstrap gitlab](../cmd/tk_bootstrap_gitlab.md).
!!! hint "Idempotency"
It is safe to run the bootstrap command as many times as you want.
If the toolkit components are present on the cluster,
the bootstrap command will perform an upgrade if needed.
You can target a specific toolkit [version](https://github.com/fluxcd/toolkit/releases)
with `tk bootstrap --version=<semver>`.
## Staging workflow
Clone the repository with:
```sh
git clone https://github.com/$GITHUB_USER/fleet-infra
cd fleet-infra
```
Create a git source pointing to a public repository master branch:
```sh
tk create source git webapp \
--url=https://github.com/stefanprodan/podinfo \
--branch=master \
--interval=30s \
--export > ./staging-cluster/webapp-source.yaml
```
Create a kustomization for synchronizing the common manifests on the cluster:
```sh
tk create kustomization webapp-common \
--source=webapp \
--path="./deploy/webapp/common" \
--prune=true \
--validate=client \
--interval=1h \
--export > ./staging-cluster/webapp-common.yaml
```
Create a kustomization for the backend service that depends on common:
```sh
tk create kustomization webapp-backend \
--depends-on=webapp-common \
--source=webapp \
--path="./deploy/webapp/backend" \
--prune=true \
--validate=client \
--interval=10m \
--health-check="Deployment/backend.webapp" \
--health-check-timeout=2m \
--export > ./staging-cluster/webapp-backend.yaml
```
Create a kustomization for the frontend service that depends on backend:
```sh
tk create kustomization webapp-frontend \
--depends-on=webapp-backend \
--source=webapp \
--path="./deploy/webapp/frontend" \
--prune=true \
--validate=client \
--interval=10m \
--health-check="Deployment/frontend.webapp" \
--health-check-timeout=2m \
--export > ./staging-cluster/webapp-frontend.yaml
```
Push changes to origin:
```sh
git add -A && git commit -m "add staging webapp" && git push
```
In about 30s the synchronization should start:
```console
$ watch tk get kustomizations
✔ gitops-system last applied revision master/35d5765a1acb9e9ce66cad7274c6fe03eee1e8eb
✔ webapp-backend reconciling
✔ webapp-common last applied revision master/f43f9b2eb6766e07f318d266a99d2ec7c940b0cf
✗ webapp-frontend dependency 'gitops-system/webapp-backend' is not ready
```
When the synchronization finishes you can check that the webapp services are running:
```console
$ kubectl -n webapp get deployments,services
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/backend 1/1 1 1 4m1s
deployment.apps/frontend 1/1 1 1 3m31s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/backend ClusterIP 10.52.10.22 <none> 9898/TCP,9999/TCP 4m1s
service/frontend ClusterIP 10.52.9.85 <none> 80/TCP 3m31s
```
!!! tip
From this moment forward, any changes made to the webapp
Kubernetes manifests in the master branch will be synchronised with the staging cluster.
If a Kubernetes manifest is removed from the webapp repository, the reconciler will remove it from your cluster.
If you delete a kustomization from the `fleet-infra` repo, the reconciler will remove all Kubernetes objects that
were previously applied from that kustomization.
If you alter the webapp deployment using `kubectl edit`, the changes will be reverted to match
the state described in git. When dealing with an incident, you can pause the recitation of a
kustomization with `tk suspend kustomization <name>`. Once the debugging session
is over, you can re-enable the reconciliation with `tk resume kustomization <name>`.
## Production bootstrap
On production clusters, you may wish to deploy stable releases of an application.
When creating a git source instead of a branch, you can specify a git tag or a semver expression.
Create the production cluster using Kubernetes kind or set the kubectl context to an existing cluster:
```sh
kind create cluster --name production
kubectl cluster-info --context kind-production
```
Run the bootstrap for the production environment:
```sh
tk bootstrap github \
--owner=$GITHUB_USER \
--repository=fleet-infra \
--path=prod-cluster \
--personal
```
Pull the changes locally:
```sh
git pull
```
## Production workflow
Create a git source using a semver range to target stable releases:
```sh
tk create source git webapp \
--url=https://github.com/stefanprodan/podinfo \
--tag-semver=">=4.0.0 <4.0.2" \
--interval=30s \
--export > ./prod-cluster/webapp-source.yaml
```
Create a kustomization for webapp pointing to the production overlay:
```sh
tk create kustomization webapp \
--source=webapp \
--path="./deploy/overlays/production" \
--prune=true \
--validate=client \
--interval=10m \
--health-check="Deployment/frontend.production" \
--health-check="Deployment/backend.production" \
--health-check-timeout=2m \
--export > ./prod-cluster/webapp-production.yaml
```
Push changes to origin:
```sh
git add -A && git commit -m "add prod webapp" && git push
```
List git sources:
```console
$ tk get sources git
✔ gitops-system last fetched revision master/99072ee132abdead8b7799d7891eae2f524eb73d
✔ webapp last fetched revision 4.0.1/113360052b3153e439a0cf8de76b8e3d2a7bdf27
```
The kubectl equivalent is `kubectl -n gitops-system get gitrepositories`.
List kustomization:
```console
$ tk get kustomizations
✔ gitops-system last applied revision master/99072ee132abdead8b7799d7891eae2f524eb73d
✔ webapp last applied revision 4.0.1/113360052b3153e439a0cf8de76b8e3d2a7bdf27
```
The kubectl equivalent is `kubectl -n gitops-system get kustomizations`.
If you want to upgrade to the latest 4.x version, you can change the semver expression to:
```sh
tk create source git webapp \
--url=https://github.com/stefanprodan/podinfo \
--tag-semver=">=4.0.0 <5.0.0" \
--interval=30s \
--export > ./prod-cluster/webapp-source.yaml
git add -A && git commit -m "update prod webapp" && git push
```
Trigger a git sync:
```console
$ tk sync ks gitops-system --with-source
► annotating source gitops-system
✔ source annotated
◎ waiting for git sync
✔ git sync completed
✔ fetched revision master/d751ea264d48bf0db8b588d1d08184834ac8fec9
◎ waiting for kustomization sync
✔ kustomization sync completed
✔ applied revision master/d751ea264d48bf0db8b588d1d08184834ac8fec9
```
The kubectl equivalent is `kubectl -n gitops-system annotate gitrepository/gitops-system source.fluxcd.io/syncAt="$(date +%s)"`.
Wait for the webapp to be upgraded:
```console
$ watch tk get kustomizations
✔ gitops-system last applied revision master/d751ea264d48bf0db8b588d1d08184834ac8fec9
✔ webapp last applied revision 4.0.5/f43f9b2eb6766e07f318d266a99d2ec7c940b0cf
```

View File

@@ -0,0 +1,101 @@
# Setup Notifications
When operating a cluster, different teams may wish to receive notifications about
the status of their GitOps pipelines.
For example, the on-call team would receive alerts about reconciliation
failures in the cluster, while the dev team may wish to be alerted when a new version
of an app was deployed and if the deployment is healthy.
## Prerequisites
* [Get started guide](../get-started/index.md)
The GitOps toolkit controllers emit Kubernetes events whenever a resource status changes.
You can use the [notification-controller](../components/notification/controller.md)
to forward these events to Slack, Microsoft Teams, Discord or Rocket chart.
The notification controller is part of the default toolkit installation.
## Define a provider
First create a secret with your Slack incoming webhook:
```sh
kubectl -n gitops-system create secret generic slack-url \
--from-literal=address=https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
```
Note that the secret must contain an `address` field,
it can be a Slack, Microsoft Teams, Discord or Rocket webhook URL.
Create a notification provider for Slack by referencing the above secret:
```yaml
apiVersion: notification.fluxcd.io/v1alpha1
kind: Provider
metadata:
name: slack
namespace: gitops-system
spec:
type: slack
channel: general
secretRef:
name: slack-url
```
The provider type can be `slack`, `msteams`, `discord`, `rocket` or `webhook`.
When type `webhook` is specified, the notification controller will post the incoming
[event](../components/notification/event.md) in JSON format to the webhook address.
This way you can create custom handlers that can store the events in
Elasticsearch, CloudWatch, Stackdriver, etc.
## Define an alert
Create an alert definition for the webapp kustomizations:
```yaml
apiVersion: notification.fluxcd.io/v1alpha1
kind: Alert
metadata:
name: on-call-webapp
namespace: gitops-system
spec:
providerRef:
name: slack
eventSeverity: info
eventSources:
- kind: Kustomization
name: webapp-backend
- kind: Kustomization
name: webapp-frontend
```
Apply the above files or commit them to the `fleet-infra` repository.
To verify that the alert has been acknowledge by the notification controller do:
```console
$ kubectl -n gitops-system get alerts
NAME READY STATUS AGE
on-call-webapp True Initialized 1m
```
Multiple alerts can be used to send notifications to different channels or Slack organizations.
The event severity can be set to `info` or `error`.
When the severity is set to `error`, the kustomize controller will alert on any error
encountered during the reconciliation process.
This includes kustomize build and validation errors,
apply errors and health check failures.
![error alert](../diagrams/slack-error-alert.png)
When the verbosity is set to `info`, the controller will alert if:
* a Kubernetes object was created, updated or deleted
* heath checks are passing
* a dependency is delaying the execution
* an error occurs
![info alert](../diagrams/slack-info-alert.png)

49
docs/index.md Normal file
View File

@@ -0,0 +1,49 @@
# GitOps Toolkit
The GitOps Toolkit is a set of composable APIs and specialized tools
that can be used to build a Continuous Delivery platform on top of Kubernetes.
These tools are built with Kubernetes controller-runtime libraries and they
can be dynamically configured with Kubernetes custom resources either by
cluster admins or by other automated tools.
The GitOps Toolkit components interact with each other via Kubernetes
events and are responsible for the reconciliation of their designated API objects.
!!! hint "Work in Progress"
We envision a future where **Flux v2** and **Helm Operator v2** will be assembled from
the GitOps Toolkit components. The Flux CD team is looking for feedback and help as
the toolkit is in an active experimentation phase.
If you wish to take part in this quest please reach out to us on Slack and GitHub.
![overview](diagrams/tk-feature.png)
Target features:
- Source management
- Kustomize and Helm support
- Event-based and on-a-schedule reconciliation
- Role-based reconciliation (multi-tenancy)
- Health assessment (clusters and workloads)
- Dependency management (infra and workloads)
- Alerting to external systems (webhook senders)
- External events handling (webhook receivers)
- Source write-back (automated patching)
- Policy driven validation (OPA, admission controllers)
- Seamless integration with Git providers (GitHub, GitLab, BitBucket)
- Interoperability with workflow providers (GitHub Actions, Tekton, Argo)
- Interoperability with CAPI providers
Components:
- [Toolkit CLI](https://github.com/fluxcd/toolkit)
- [Source Controller](components/source/controller.md)
- [GitRepository CRD](components/source/gitrepositories.md)
- [HelmRepository CRD](components/source/helmrepositories.md)
- [Kustomize Controller](components/kustomize/controller.md)
- [Kustomization CRD](components/kustomize/kustomization.md)
- [Notification Controller](components/notification/controller.md)
- [Provider CRD](components/notification/provider.md)
- [Alert CRD](components/notification/alert.md)
- Helm Controller (TBA)
To get started with the toolkit please follow this [guide](get-started/index.md).

View File

@@ -2,11 +2,6 @@
To release a new version the following steps should be followed:
1. Create a new branch from `master` i.e. `release-<next semver>`. This
will function as your release preparation branch.
1. Change the `VERSION` value in `cmd/tk/main.go` to that of the
semver release you are going to make. Commit and push your changes.
1. Create a PR for your release branch and get it merged into `master`.
1. Create a `<next semver>` tag for the merge commit in `master` and
1. Create a `<next semver>` tag form `master` and
push it to remote.
1. Confirm CI builds and releases the newly tagged version.

81
docs/roadmap/index.md Normal file
View File

@@ -0,0 +1,81 @@
# Roadmap
!!! hint "Work in Progress"
We will be building the roadmap together with the Flux community,
our end-users and everyone who is interested in integrating with us.
So a lot of this is still TBD - read this as our shopping list of
ideas after some brainstorming as Flux maintainers.
## The road to Flux v2
### Flux read-only feature parity
This would be the first stepping stone: we want the GitOps Toolkit to be on-par with today's Flux in
[read-only mode](https://github.com/fluxcd/flux/blob/master/docs/faq.md#can-i-run-flux-with-readonly-git-access)
and [FluxCloud](https://github.com/justinbarrick/fluxcloud) notifications.
Goals
- Offer an in-place migration tool for those that are using Flux in read-only mode to synchronize plain manifests
- Offer a migration guide for those that are using Flux in read-only mode to synchronize Kustomize overlays
- Offer a dedicated component for forwarding events to external messaging platforms
Non-Goals
- Migrate users that are using Flux to run custom scripts with `flux.yaml`
- Automate the migration of `flux.yaml` kustomize users
Tasks
- Review the git source and kustomize APIs
- ~~Design the events API~~
- Implement events in source and kustomize controllers
- Implement Prometheus metrics in source and kustomize controllers
- Make the kustomize-controller apply/gc events on-par with Flux v1 apply events
- ~~Design the notifications and events filtering API~~
- ~~Implement a notification controller for Slack, MS Teams, Discord, Rocket~~
- Implement the migration command in tk
- Create a migration guide for `flux.yaml` kustomize users
### Flux image update feature parity
Goals
- Offer a dedicated component that can replace Flux v1 image update feature
Non-Goals
- Maintain backwards compatibility with Flux v1 annotations
Tasks
- Design the Git push API
- Implement Git push in source controller
- Design the image scanning API
- Implement an image scanning controller
- Design the manifests patching component
- Implement the image scan/patch/push workflow
- Integrate the new components in the toolkit assembler
- Create a migration guide from Flux annotations
## The road to Helm Operator v2
### Helm v3 feature parity
Goals
- Offer a migration guide for those that are using Helm Operator with Helm v3 and Helm repositories
Non-Goals
- Migrate users that are using Helm v2
- Migrate users that are using Helm charts from Git
Tasks
- Review the Helm release, chart and repository APIs
- Design Helm releases based on source API
- Implement a Helm controller for Helm v3 covering all the current release options
- Implement events in Helm controller
- Implement Prometheus metrics in Helm controller
- Create a migration guide for Helm Operator users

15
go.mod
View File

@@ -4,13 +4,18 @@ go 1.14
require (
github.com/blang/semver v3.5.1+incompatible
github.com/fluxcd/kustomize-controller v0.0.1-beta.2
github.com/fluxcd/source-controller v0.0.1-beta.2
github.com/go-git/go-git/v5 v5.0.0
github.com/google/go-github/v32 v32.0.0
github.com/fluxcd/kustomize-controller v0.0.1
github.com/fluxcd/pkg v0.0.1
github.com/fluxcd/source-controller v0.0.1
github.com/golang/protobuf v1.4.2 // indirect
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
github.com/manifoldco/promptui v0.7.0
github.com/spf13/cobra v1.0.0
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.24.0 // indirect
k8s.io/api v0.18.2
k8s.io/apimachinery v0.18.2
k8s.io/client-go v0.18.2

63
go.sum
View File

@@ -168,10 +168,12 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwC
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fluxcd/kustomize-controller v0.0.1-beta.2 h1:3EM2OFR9z8FiILDgzqHHqzSx3mO4KT8xG1gKTevD42E=
github.com/fluxcd/kustomize-controller v0.0.1-beta.2/go.mod h1:mLeipvpQkyof6b5IHNtqeA8CmbjfVIf92UyKkpeBY98=
github.com/fluxcd/source-controller v0.0.1-beta.2 h1:XOtc+tSf/8Q0bTVla2L5FdCMMjJWFSPWX/o4/h4OUv0=
github.com/fluxcd/source-controller v0.0.1-beta.2/go.mod h1:tmscNdCxEt7+Xt2g1+bI38hMPw2leYMFAaCn4UlMGuw=
github.com/fluxcd/kustomize-controller v0.0.1 h1:F2wg9c5nMUEnPHgs44HMY1/2UAXXaYcmpj7WeOzf9p0=
github.com/fluxcd/kustomize-controller v0.0.1/go.mod h1:sSIy+Y924OGHW2anzZvD53BbgjSOO4mONTTG2+UTEhM=
github.com/fluxcd/pkg v0.0.1 h1:yECp5SBjX7vUBOjd3KYBoVQwt22A0u1SZJjYV4PduAk=
github.com/fluxcd/pkg v0.0.1/go.mod h1:3DgEcVmkVYrA/BDb/fyDIJllxK++c/ovLCMPRlkAp9Y=
github.com/fluxcd/source-controller v0.0.1 h1:17/b/Zcb3OUkUoo03W+L7TGwkCKG23K9HrgL+d5WMXE=
github.com/fluxcd/source-controller v0.0.1/go.mod h1:tmscNdCxEt7+Xt2g1+bI38hMPw2leYMFAaCn4UlMGuw=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
@@ -195,6 +197,8 @@ github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
github.com/go-git/go-git/v5 v5.0.0 h1:k5RWPm4iJwYtfWoxIJy4wJX9ON7ihPeZZYC1fLYDnpg=
github.com/go-git/go-git/v5 v5.0.0/go.mod h1:oYD8y9kWsGINPFJoLdaScGCN6dlKg23blmClfZwtUVA=
github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk=
github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
@@ -293,6 +297,14 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0=
@@ -317,6 +329,7 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v32 v32.0.0 h1:q74KVb22spUq0U5HqZ9VCYqQz8YRuOtL/39ZnfwO+NM=
@@ -360,7 +373,15 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-retryablehttp v0.6.4 h1:BbgctKO892xEyOXnGiaAwIoSq1QZ/SS4AhjoAh9DnfY=
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM=
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
@@ -377,6 +398,8 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@@ -617,6 +640,8 @@ github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xanzy/go-gitlab v0.32.1 h1:eKGfAP2FWbqStD7DtGoRBb18IYwjuCxdtEVea2rNge4=
github.com/xanzy/go-gitlab v0.32.1/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -669,6 +694,8 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -686,6 +713,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -696,6 +724,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -707,11 +736,16 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -748,6 +782,8 @@ golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hq
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -758,6 +794,10 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -797,9 +837,12 @@ google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -808,6 +851,7 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -817,6 +861,17 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -15,6 +15,12 @@ The install script does the following:
* copies the tk binary to `/usr/local/bin`
* removes the temporary directory
If you want to use tk as a kubectl plugin, rename the binary to `kubectl-tk`:
```sh
mv /usr/local/bin/tk /usr/local/bin/kubectl-tk
```
## Build from source
Clone the repository:

View File

@@ -1,5 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/kustomize-controller/config//crd?ref=v0.0.1-beta.2
- github.com/fluxcd/kustomize-controller/config//manager?ref=v0.0.1-beta.2
- github.com/fluxcd/kustomize-controller/config//crd?ref=v0.0.2
- github.com/fluxcd/kustomize-controller/config//manager?ref=v0.0.2
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: kustomize-controller
path: patch.yaml

View File

@@ -0,0 +1,3 @@
- op: add
path: /spec/template/spec/containers/0/args/0
value: --events-addr=http://notification-controller/

View File

@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/notification-controller/config//crd?ref=v0.0.1-alpha.2
- github.com/fluxcd/notification-controller/config//manager?ref=v0.0.1-alpha.2

View File

@@ -1,5 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/source-controller/config//crd?ref=v0.0.1-beta.2
- github.com/fluxcd/source-controller/config//manager?ref=v0.0.1-beta.2
- github.com/fluxcd/source-controller/config//crd?ref=v0.0.1
- github.com/fluxcd/source-controller/config//manager?ref=v0.0.1

View File

@@ -5,6 +5,7 @@ resources:
- namespace.yaml
- ../bases/source-controller
- ../bases/kustomize-controller
- ../bases/notification-controller
- ../rbac
- ../policies
transformers:

View File

@@ -9,6 +9,9 @@ rules:
- apiGroups: ['kustomize.fluxcd.io']
resources: ['*']
verbs: ['*']
- apiGroups: ['notification.fluxcd.io']
resources: ['*']
verbs: ['*']
- apiGroups:
- ""
resources:

92
mkdocs.yml Normal file
View File

@@ -0,0 +1,92 @@
site_name: GitOps Toolkit
site_description: A toolkit for assembling GitOps pipelines on Kubernetes
site_author: The Flux CD contributors
site_url: https://toolkit.fluxcd.io
repo_name: fluxcd/toolkit
repo_url: https://github.com/fluxcd/toolkit
edit_uri: ""
theme:
name: material
logo: _files/flux-icon@2x.png
language: en
palette:
primary: blue
accent: indigo
custom_dir: mkdocs/
docs_dir: docs
extra_css:
- _static/custom.css
plugins:
- search
markdown_extensions:
- admonition
- meta
- codehilite:
guess_lang: false
- toc:
permalink: true
- pymdownx.superfences:
highlight_code: true
- pymdownx.tabbed
- pymdownx.tilde
nav:
- Introduction: index.md
- Get Started: get-started/index.md
- Guides:
- Setup Notifications: guides/notifications.md
- Toolkit Components:
- Source Controller:
- Overview: components/source/controller.md
- GitRepository CRD: components/source/gitrepositories.md
- HelmRepository CRD: components/source/helmrepositories.md
- Source API Reference: components/source/api.md
- Kustomize Controller:
- Overview: components/kustomize/controller.md
- Kustomization CRD: components/kustomize/kustomization.md
- Kustomize API Reference: components/kustomize/api.md
- Notification Controller:
- Overview: components/notification/controller.md
- Provider CRD: components/notification/provider.md
- Alert CRD: components/notification/alert.md
- Event: components/notification/event.md
- Notification API Reference: components/notification/api.md
- Toolkit CLI:
- Overview: cmd/tk.md
- Bootstrap: cmd/tk_bootstrap.md
- Bootstrap github: cmd/tk_bootstrap_github.md
- Bootstrap gitlab: cmd/tk_bootstrap_gitlab.md
- Check: cmd/tk_check.md
- Create: cmd/tk_create.md
- Create kustomization: cmd/tk_create_kustomization.md
- Create source: cmd/tk_create_source.md
- Create source git: cmd/tk_create_source_git.md
- Delete: cmd/tk_delete.md
- Delete kustomization: cmd/tk_delete_kustomization.md
- Delete source: cmd/tk_delete_source.md
- Delete source git: cmd/tk_delete_source_git.md
- Export: cmd/tk_export.md
- Export kustomization: cmd/tk_export_kustomization.md
- Export source: cmd/tk_export_source.md
- Export source git: cmd/tk_export_source_git.md
- Get: cmd/tk_get.md
- Get kustomizations: cmd/tk_get_kustomizations.md
- Get sources: cmd/tk_get_sources.md
- Get sources git: cmd/tk_get_sources_git.md
- Install: cmd/tk_install.md
- Resume: cmd/tk_resume.md
- Resume kustomization: cmd/tk_resume_kustomization.md
- Suspend: cmd/tk_suspend.md
- Suspend kustomization: cmd/tk_suspend_kustomization.md
- Sync: cmd/tk_sync.md
- Sync kustomization: cmd/tk_sync_kustomization.md
- Sync source: cmd/tk_sync_source.md
- Sync source git: cmd/tk_sync_source_git.md
- Uninstall: cmd/tk_uninstall.md
- Roadmap: roadmap/index.md

32
mkdocs/main.html Normal file
View File

@@ -0,0 +1,32 @@
{% extends "base.html" %}
{% block extrahead %}
<meta property="og:url" content="{{ page.canonical_url }}">
{% if page and page.meta and page.meta.title %}
<meta property="og:title" content="{{ page.meta.title }}">
{% elif page and page.title and not page.is_homepage %}
<meta property="og:title" content="{{ page.title }} - {{ config.site_name }}">
{% else %}
<meta property="og:title" content="{{ config.site_name }}">
{% endif %}
<meta property="og:description" content="{{ config.site_description }}">
<meta property="og:image" content="https://toolkit.fluxcd.io/_files/toolkit-icon.png">
<meta property="og:image:alt" content="GitOps Toolkit">
<meta property="og:image:type" content="image/png">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@stefanprodan">
<meta name="twitter:creator" content="@stefanprodan">
{% if page and page.meta and page.meta.title %}
<meta property="twitter:title" content="{{ page.meta.title }}">
{% elif page and page.title and not page.is_homepage %}
<meta property="twitter:title" content="{{ page.title }} - {{ config.site_name }}">
{% else %}
<meta property="twitter:title" content="{{ config.site_name }}">
{% endif %}
<meta name="twitter:description" content="{{ config.site_description }}">
<meta name="twitter:image" content="https://toolkit.fluxcd.io/_files/toolkit-icon.png">
<meta name="twitter:image:alt" content="GitOps Toolkit">
{% endblock %}

29
pkg/log/log.go Normal file
View File

@@ -0,0 +1,29 @@
/*
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 log
type Logger interface {
// Actionf logs a formatted action message.
Actionf(format string, a ...interface{})
// Generatef logs a formatted generate message.
Generatef(format string, a ...interface{})
// Waitingf logs a formatted waiting message.
Waitingf(format string, a ...interface{})
// Waitingf logs a formatted success message.
Successf(format string, a ...interface{})
// Failuref logs a formatted failure message.
Failuref(format string, a ...interface{})
}

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