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

Compare commits

...

33 Commits

Author SHA1 Message Date
Stefan Prodan
ebf742d272 Merge pull request #219 from fluxcd/bootstrap-branch
Add branch flag to bootstrap cmd
2020-09-09 17:59:30 +03:00
stefanprodan
a7b1b04920 Add bootstrap reinstall e2e test 2020-09-09 17:27:56 +03:00
stefanprodan
1218d6abe8 Add branch flag to bootstrap cmd 2020-09-09 16:41:48 +03:00
Stefan Prodan
f9d546676b Merge pull request #218 from fluxcd/refac
Add GitHub bootstrap e2e test
2020-09-09 14:15:33 +03:00
stefanprodan
afef6960b9 Cleanup GitHub e2e repo 2020-09-09 14:03:26 +03:00
stefanprodan
f6626b8975 Add GitHub bootstrap e2e test 2020-09-09 08:56:55 +03:00
stefanprodan
b1e66f81ab Add label validation 2020-09-08 20:08:28 +03:00
Stefan Prodan
9cc018e618 Merge pull request #216 from fluxcd/labels
Add label arg to create commands
2020-09-08 18:14:31 +03:00
stefanprodan
797cd9bea2 Add label arg to create commands 2020-09-08 18:03:04 +03:00
Hidde Beydals
9dbfca3d7a Merge pull request #212 from fluxcd/refactor-hr-source-kind-validation
Refactor HelmRelease chart source kind validation
2020-09-07 12:02:34 +02:00
Hidde Beydals
f18d1efdcb Refactor HelmRelease chart source kind validation 2020-09-07 11:13:15 +02:00
stefanprodan
29a9b89224 Set Homebrew formula name 2020-09-07 12:04:27 +03:00
Stefan Prodan
11b5b9808b Merge pull request #211 from fluxcd/homebrew
Publish Homebrew formula
2020-09-07 11:55:10 +03:00
stefanprodan
ca1f84d22b Publish Homebrew formula 2020-09-07 11:41:06 +03:00
Stefan Prodan
d6c6c88e6e Merge pull request #209 from fluxcd/sops
Mozilla SOPS
2020-09-06 15:02:36 +03:00
stefanprodan
ee33702463 Add Mozilla SOPS guide to docs 2020-09-06 14:24:33 +03:00
stefanprodan
8b6995e9ec Add decryption flags to create kustomization cmd 2020-09-06 13:56:56 +03:00
Stefan Prodan
36ba8f0fcb Merge pull request #207 from fluxcd/kustomize-controller-v0.0.10
Update kustomize-controller to v0.0.10
2020-09-05 11:19:33 +03:00
stefanprodan
bfb560ec50 Update kustomize-controller to v0.0.10 2020-09-05 11:04:41 +03:00
Stefan Prodan
78bb11dcbf Merge pull request #204 from fluxcd/ghcr
Use GitHub Container Registry for AMD64/ARM64 images
2020-09-04 17:35:25 +03:00
stefanprodan
5c8d00665f Use GitHub Container Registry for AMD64/ARM64 images 2020-09-04 17:18:33 +03:00
Stefan Prodan
f4d78cc08e Merge pull request #202 from fluxcd/arch
Add ARM64 support to install/bootstrap
2020-09-04 16:37:03 +03:00
stefanprodan
2aa395ba12 Update source and helm controllers
helm-controller/api v0.0.7
source-controller/api v0.0.14
2020-09-04 16:23:21 +03:00
Hidde Beydals
ac862e6822 Merge pull request #201 from fluxcd/update-hr-create-docs
Update `gotk create helmrelease` examples
2020-09-04 14:24:37 +02:00
stefanprodan
1b55ead16e Add ARM64 to install docs and script 2020-09-04 15:10:42 +03:00
stefanprodan
b24727ec22 Update kustomize-controller to v0.0.9 2020-09-04 14:28:37 +03:00
stefanprodan
2768926683 Publish gotk linux/arm64 binary 2020-09-04 12:54:26 +03:00
stefanprodan
3f07bd6471 Add arch flag to install/bootstrap 2020-09-04 12:46:08 +03:00
Hidde Beydals
2f861f19c0 Update gotk create helmrelease examples
To better reflect optional fields and highlight specific configuration
options.
2020-09-03 19:31:19 +02:00
Hidde Beydals
6b397cff73 Merge pull request #200 from scottrigby/docs-gotk-create-hr-fix
Docs: fix gotk create helmrelease examples
2020-09-03 17:45:37 +02:00
Scott Rigby
44a3cf86d3 Docs: fix gotk create helmrelease examples
Signed-off-by: Scott Rigby <scott@r6by.com>
2020-09-03 17:39:12 +02:00
Hidde Beydals
dfb0a40293 Merge pull request #199 from fluxcd/docs/helmrelease-git-guide
Document GitRepository source in HelmRelease guide
2020-09-03 16:48:22 +02:00
Hidde Beydals
7719dd378b docs: GitRepository source in HelmRelease guide 2020-09-03 15:09:12 +02:00
39 changed files with 728 additions and 207 deletions

74
.github/workflows/bootstrap.yaml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: bootstrap
on:
push:
branches:
- '*'
jobs:
github:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Restore Go cache
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.14.x
- name: Setup Kubernetes
uses: engineerd/setup-kind@v0.4.0
- name: Set outputs
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Build
run: sudo go build -o ./bin/gotk ./cmd/gotk
- name: bootstrap init
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: bootstrap no-op
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: uninstall
run: |
./bin/gotk suspend kustomization gitops-system
./bin/gotk uninstall --resources --crds -s
- name: bootstrap reinstall
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: delete repository
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster \
--delete
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: Debug failure
if: failure()
run: |
kubectl -n gitops-system get all
kubectl -n gitops-system logs deploy/source-controller
kubectl -n gitops-system logs deploy/kustomize-controller

View File

@@ -82,3 +82,4 @@ jobs:
args: release --release-notes=/tmp/release.txt --skip-validate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}

View File

@@ -8,9 +8,24 @@ builds:
- linux
goarch:
- amd64
- arm64
env:
- CGO_ENABLED=0
archives:
- name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
files:
- none*
brews:
- name: gotk
tap:
owner: fluxcd
name: homebrew-tap
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
folder: Formula
homepage: "https://toolkit.fluxcd.io/"
description: "GitOps Toolkit CLI"
dependencies:
- name: kubectl
type: optional
test: |
system "#{bin}/gotk --version"

View File

@@ -23,7 +23,6 @@ import (
"os"
"path"
"path/filepath"
"sigs.k8s.io/yaml"
"strings"
"time"
@@ -33,6 +32,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
@@ -49,10 +49,12 @@ var (
bootstrapComponents []string
bootstrapRegistry string
bootstrapImagePullSecret string
bootstrapArch string
bootstrapBranch string
)
const (
bootstrapBranch = "master"
bootstrapDefaultBranch = "master"
bootstrapInstallManifest = "toolkit-components.yaml"
bootstrapSourceManifest = "toolkit-source.yaml"
bootstrapKustomizationManifest = "toolkit-kustomization.yaml"
@@ -63,10 +65,14 @@ func init() {
"toolkit version")
bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapComponents, "components", defaultComponents,
"list of components, accepts comma-separated values")
bootstrapCmd.PersistentFlags().StringVar(&bootstrapRegistry, "registry", "docker.io/fluxcd",
bootstrapCmd.PersistentFlags().StringVar(&bootstrapRegistry, "registry", "ghcr.io/fluxcd",
"container registry where the toolkit images are published")
bootstrapCmd.PersistentFlags().StringVar(&bootstrapImagePullSecret, "image-pull-secret", "",
"Kubernetes secret name used for pulling the toolkit images from a private registry")
bootstrapCmd.PersistentFlags().StringVar(&bootstrapArch, "arch", "amd64",
"arch can be amd64 or arm64")
bootstrapCmd.PersistentFlags().StringVar(&bootstrapBranch, "branch", bootstrapDefaultBranch,
"default branch (for GitHub this must match the default branch setting for the organization)")
rootCmd.AddCommand(bootstrapCmd)
}
@@ -78,7 +84,7 @@ func generateInstallManifests(targetPath, namespace, tmpDir string) (string, err
return "", fmt.Errorf("generating manifests failed: %w", err)
}
if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, bootstrapRegistry, bootstrapImagePullSecret, gotkDir); err != nil {
if err := genInstallManifests(bootstrapVersion, namespace, bootstrapComponents, bootstrapRegistry, bootstrapImagePullSecret, bootstrapArch, gotkDir); err != nil {
return "", fmt.Errorf("generating manifests failed: %w", err)
}
@@ -111,8 +117,8 @@ func applyInstallManifests(ctx context.Context, manifestPath string, components
return nil
}
func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, interval time.Duration) error {
gvk := sourcev1.GroupVersion.WithKind("GitRepository")
func generateSyncManifests(url, branch, name, namespace, targetPath, tmpDir string, interval time.Duration) error {
gvk := sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)
gitRepository := sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
@@ -128,7 +134,7 @@ func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, inte
Duration: interval,
},
Reference: &sourcev1.GitRepositoryRef{
Branch: "master",
Branch: branch,
},
SecretRef: &corev1.LocalObjectReference{
Name: name,
@@ -145,7 +151,7 @@ func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, inte
return err
}
gvk = kustomizev1.GroupVersion.WithKind("Kustomization")
gvk = kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)
kustomization := kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,

View File

@@ -55,6 +55,9 @@ the bootstrap command will perform an upgrade if needed.`,
# Run bootstrap for a private repo hosted on GitHub Enterprise
gotk bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap github --owner=<organization> --repository=<repo name> --branch=main
`,
RunE: bootstrapGitHubCmdRun,
}
@@ -68,6 +71,7 @@ var (
ghHostname string
ghPath string
ghTeams []string
ghDelete bool
)
const (
@@ -84,6 +88,9 @@ func init() {
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")
bootstrapGitHubCmd.Flags().BoolVar(&ghDelete, "delete", false, "delete repository (used for testing only)")
bootstrapGitHubCmd.Flags().MarkHidden("delete")
bootstrapCmd.AddCommand(bootstrapGitHubCmd)
}
@@ -93,6 +100,10 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("%s environment variable not found", git.GitHubTokenName)
}
if !utils.containsItemString(supportedArch, bootstrapArch) {
return fmt.Errorf("arch %s is not supported, can be %v", bootstrapArch, supportedArch)
}
repository, err := git.NewRepository(ghRepository, ghOwner, ghHostname, ghToken, "gotk", ghOwner+"@users.noreply.github.com")
if err != nil {
return err
@@ -103,11 +114,6 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
IsPersonal: ghPersonal,
}
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", namespace)
if err != nil {
return err
@@ -117,6 +123,14 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
if ghDelete {
if err := provider.DeleteRepository(ctx, repository); err != nil {
return err
}
logger.Successf("repository deleted")
return nil
}
// create GitHub repository if doesn't exists
logger.Actionf("connecting to %s", ghHostname)
changed, err := provider.CreateRepository(ctx, repository)
@@ -169,6 +183,11 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
logger.Successf("components are up to date")
}
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
// determine if repo synchronization is working
isInstall := shouldInstallManifests(ctx, kubeClient, namespace)
@@ -207,22 +226,19 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
}
// configure repo synchronization
if isInstall {
// generate source and kustomization manifests
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, ghPath, tmpDir, ghInterval); err != nil {
return err
}
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), bootstrapBranch, namespace, namespace, ghPath, tmpDir, ghInterval); err != nil {
return err
}
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests"); err != nil {
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests"); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("sync manifests pushed")
}
logger.Successf("sync manifests pushed")
// apply manifests and waiting for sync
logger.Actionf("applying sync manifests")

View File

@@ -52,6 +52,9 @@ the bootstrap command will perform an upgrade if needed.`,
# Run bootstrap for a private repo hosted on a GitLab server
gotk bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main
`,
RunE: bootstrapGitLabCmdRun,
}
@@ -86,6 +89,10 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("%s environment variable not found", git.GitLabTokenName)
}
if !utils.containsItemString(supportedArch, bootstrapArch) {
return fmt.Errorf("arch %s is not supported, can be %v", bootstrapArch, supportedArch)
}
repository, err := git.NewRepository(glRepository, glOwner, glHostname, glToken, "gotk", glOwner+"@users.noreply.gitlab.com")
if err != nil {
return err
@@ -191,22 +198,19 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
}
// 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
}
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), bootstrapBranch, 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 {
// 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
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("sync manifests pushed")
}
logger.Successf("sync manifests pushed")
// apply manifests and waiting for sync
logger.Actionf("applying sync manifests")

View File

@@ -17,8 +17,12 @@ limitations under the License.
package main
import (
"fmt"
"strings"
"time"
"k8s.io/apimachinery/pkg/util/validation"
"github.com/spf13/cobra"
)
@@ -31,10 +35,38 @@ var createCmd = &cobra.Command{
var (
interval time.Duration
export bool
labels []string
)
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().StringSliceVar(&labels, "label", nil,
"set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)")
rootCmd.AddCommand(createCmd)
}
func parseLabels() (map[string]string, error) {
result := make(map[string]string)
for _, label := range labels {
// validate key value pair
parts := strings.Split(label, "=")
if len(parts) != 2 {
return nil, fmt.Errorf("invalid label format '%s', must be key=value", label)
}
// validate label name
if errors := validation.IsQualifiedName(parts[0]); len(errors) > 0 {
return nil, fmt.Errorf("invalid label '%s': %v", parts[0], errors)
}
// validate label value
if errors := validation.IsValidLabelValue(parts[1]); len(errors) > 0 {
return nil, fmt.Errorf("invalid label value '%s': %v", parts[1], errors)
}
result[parts[0]] = parts[1]
}
return result, nil
}

View File

@@ -42,37 +42,41 @@ var createHelmReleaseCmd = &cobra.Command{
Aliases: []string{"hr"},
Short: "Create or update a HelmRelease resource",
Long: "The helmrelease create command generates a HelmRelease resource for a given HelmRepository source.",
Example: ` # Create a HelmRelease from a HelmRepository source
Example: ` # Create a HelmRelease with a chart from a HelmRepository source
gotk create hr podinfo \
--interval=10m \
--release-name=podinfo \
--target-namespace=default \
--source=HelmRepository/podinfo \
--chart=podinfo \
--chart-version=">4.0.0"
# Create a HelmRelease from a GitRepository source
# Create a HelmRelease with a chart from a GitRepository source
gotk create hr podinfo \
--interval=10m \
--release-name=podinfo \
--target-namespace=default \
--source=GitRepository/podinfo \
--chart=./charts/podinfo
# Create a HelmRelease with values for a local YAML file
# Create a HelmRelease with values from a local YAML file
gotk create hr podinfo \
--source=HelmRepository/podinfo \
--chart=podinfo \
--values=./my-values.yaml
# Create a HelmRelease with a custom release name
gotk create hr podinfo \
--release-name=podinfo-dev
--source=HelmRepository/podinfo \
--chart=podinfo \
# Create a HelmRelease targeting another namespace than the resource
gotk create hr podinfo \
--target-namespace=default \
--source=HelmRepository/podinfo \
--chart=podinfo \
--chart-version=4.0.5 \
--values=./my-values.yaml
--chart=podinfo
# Create a HelmRelease definition on disk without applying it on the cluster
gotk create hr podinfo \
--target-namespace=default \
--source=HelmRepository/podinfo \
--chart=podinfo \
--chart-version=4.0.5 \
--values=./values.yaml \
--export > podinfo-release.yaml
`,
@@ -90,10 +94,10 @@ var (
)
func init() {
createHelmReleaseCmd.Flags().StringVar(&hrName, "release-name", "", "name used for the Helm release, defaults to a composition of '<target-namespace>-<hr-name>'")
createHelmReleaseCmd.Flags().StringVar(&hrName, "release-name", "", "name used for the Helm release, defaults to a composition of '[<target-namespace>-]<hr-name>'")
createHelmReleaseCmd.Flags().StringVar(&hrSource, "source", "", "source that contains the chart (<kind>/<name>)")
createHelmReleaseCmd.Flags().StringVar(&hrChart, "chart", "", "Helm chart name or path")
createHelmReleaseCmd.Flags().StringVar(&hrChartVersion, "chart-version", "", "Helm chart version, accepts semver range (ignored for charts from GitRepository sources)")
createHelmReleaseCmd.Flags().StringVar(&hrChartVersion, "chart-version", "", "Helm chart version, accepts a semver range (ignored for charts from GitRepository sources)")
createHelmReleaseCmd.Flags().StringArrayVar(&hrDependsOn, "depends-on", nil, "HelmReleases that must be ready before this release can be installed")
createHelmReleaseCmd.Flags().StringVar(&hrTargetNamespace, "target-namespace", "", "namespace to install this release, defaults to the HelmRelease namespace")
createHelmReleaseCmd.Flags().StringVar(&hrValuesFile, "values", "", "local path to the values.yaml file")
@@ -111,20 +115,18 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
}
hrSourceElements := strings.Split(hrSource, "/")
if len(hrSourceElements) != 2 {
return fmt.Errorf("source must be in format <kind>/<name>")
return fmt.Errorf("invalid source '%s', must be in format <kind>/<name>", hrSource)
}
hrSourceKind, hrSourceName := hrSourceElements[0], hrSourceElements[1]
if hrSourceKind != sourcev1.HelmRepositoryKind && hrSourceKind != sourcev1.GitRepositoryKind {
return fmt.Errorf("source kind must be one of: %s", []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind})
if !utils.containsItemString(supportedHelmChartSourceKinds, hrSourceKind) {
return fmt.Errorf("source kind %s is not supported, can be %v",
hrSourceKind, supportedHelmChartSourceKinds)
}
if hrChart == "" {
return fmt.Errorf("chart name or path is required")
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
kubeClient, err := utils.kubeClient(kubeconfig)
sourceLabels, err := parseLabels()
if err != nil {
return err
}
@@ -137,6 +139,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: sourceLabels,
},
Spec: helmv2.HelmReleaseSpec{
ReleaseName: hrName,
@@ -177,6 +180,14 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
return exportHelmRelease(helmRelease)
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
logger.Actionf("applying release")
if err := upsertHelmRelease(ctx, kubeClient, helmRelease); err != nil {
return err
@@ -233,6 +244,7 @@ func upsertHelmRelease(ctx context.Context, kubeClient client.Client, helmReleas
return err
}
existing.Labels = helmRelease.Labels
existing.Spec = helmRelease.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err

View File

@@ -73,15 +73,17 @@ var createKsCmd = &cobra.Command{
}
var (
ksSource string
ksPath string
ksPrune bool
ksDependsOn []string
ksValidation string
ksHealthCheck []string
ksHealthTimeout time.Duration
ksSAName string
ksSANamespace string
ksSource string
ksPath string
ksPrune bool
ksDependsOn []string
ksValidation string
ksHealthCheck []string
ksHealthTimeout time.Duration
ksSAName string
ksSANamespace string
ksDecryptionProvider string
ksDecryptionSecret string
)
func init() {
@@ -94,6 +96,8 @@ func init() {
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")
createKsCmd.Flags().StringVar(&ksDecryptionProvider, "decryption-provider", "", "enables secrets decryption, provider can be 'sops'")
createKsCmd.Flags().StringVar(&ksDecryptionSecret, "decryption-secret", "", "set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption")
createCmd.AddCommand(createKsCmd)
}
@@ -117,10 +121,16 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
logger.Generatef("generating kustomization")
}
ksLabels, err := parseLabels()
if err != nil {
return err
}
kustomization := kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: ksLabels,
},
Spec: kustomizev1.KustomizationSpec{
DependsOn: ksDependsOn,
@@ -178,6 +188,21 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
}
}
if ksDecryptionProvider != "" {
if !utils.containsItemString(supportedDecryptionProviders, ksDecryptionProvider) {
return fmt.Errorf("decryption provider %s is not supported, can be %v",
ksDecryptionProvider, supportedDecryptionProviders)
}
kustomization.Spec.Decryption = &kustomizev1.Decryption{
Provider: ksDecryptionProvider,
}
if ksDecryptionSecret != "" {
kustomization.Spec.Decryption.SecretRef = &corev1.LocalObjectReference{Name: ksDecryptionSecret}
}
}
if export {
return exportKs(kustomization)
}
@@ -241,6 +266,7 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client, kustomiz
return err
}
existing.Labels = kustomization.Labels
existing.Spec = kustomization.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err

View File

@@ -129,10 +129,16 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("git URL parse failed: %w", err)
}
sourceLabels, err := parseLabels()
if err != nil {
return err
}
gitRepository := sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: sourceLabels,
},
Spec: sourcev1.GitRepositorySpec{
URL: sourceGitURL,
@@ -343,6 +349,7 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client, gitRepos
return err
}
existing.Labels = gitRepository.Labels
existing.Spec = gitRepository.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err

View File

@@ -19,18 +19,19 @@ package main
import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
"io/ioutil"
"net/url"
"os"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"net/url"
"os"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var createSourceHelmCmd = &cobra.Command{
@@ -91,6 +92,11 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("url is required")
}
sourceLabels, err := parseLabels()
if err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", name)
if err != nil {
return err
@@ -105,6 +111,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: sourceLabels,
},
Spec: sourcev1.HelmRepositorySpec{
URL: sourceHelmURL,
@@ -225,6 +232,7 @@ func upsertHelmRepository(ctx context.Context, kubeClient client.Client, helmRep
return err
}
existing.Labels = helmRepository.Labels
existing.Spec = helmRepository.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err
@@ -233,27 +241,3 @@ func upsertHelmRepository(ctx context.Context, kubeClient client.Client, helmRep
logger.Successf("source updated")
return nil
}
func exportHelmRepository(source sourcev1.HelmRepository) error {
gvk := sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)
export := sourcev1.HelmRepository{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: source.Name,
Namespace: source.Namespace,
},
Spec: source.Spec,
}
data, err := yaml.Marshal(export)
if err != nil {
return err
}
fmt.Println("---")
fmt.Println(string(data))
return nil
}

View File

@@ -68,7 +68,7 @@ func exportHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
}
if len(list.Items) == 0 {
logger.Failuref("no kustomizations found in %s namespace", namespace)
logger.Failuref("no helmrelease found in %s namespace", namespace)
return nil
}
@@ -101,8 +101,10 @@ func exportHelmRelease(helmRelease helmv2.HelmRelease) error {
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: helmRelease.Name,
Namespace: helmRelease.Namespace,
Name: helmRelease.Name,
Namespace: helmRelease.Namespace,
Labels: helmRelease.Labels,
Annotations: helmRelease.Annotations,
},
Spec: helmRelease.Spec,
}

View File

@@ -20,12 +20,13 @@ import (
"context"
"fmt"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
)
var exportKsCmd = &cobra.Command{
@@ -100,8 +101,10 @@ func exportKs(kustomization kustomizev1.Kustomization) error {
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: kustomization.Name,
Namespace: kustomization.Namespace,
Name: kustomization.Name,
Namespace: kustomization.Namespace,
Labels: kustomization.Labels,
Annotations: kustomization.Annotations,
},
Spec: kustomization.Spec,
}

View File

@@ -20,13 +20,14 @@ import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var exportSourceGitCmd = &cobra.Command{
@@ -110,8 +111,10 @@ func exportGit(source sourcev1.GitRepository) error {
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: source.Name,
Namespace: source.Namespace,
Name: source.Name,
Namespace: source.Namespace,
Labels: source.Labels,
Annotations: source.Annotations,
},
Spec: source.Spec,
}

View File

@@ -20,13 +20,14 @@ import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var exportSourceHelmCmd = &cobra.Command{
@@ -102,6 +103,32 @@ func exportSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
return nil
}
func exportHelmRepository(source sourcev1.HelmRepository) error {
gvk := sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)
export := sourcev1.HelmRepository{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: source.Name,
Namespace: source.Namespace,
Labels: source.Labels,
Annotations: source.Annotations,
},
Spec: source.Spec,
}
data, err := yaml.Marshal(export)
if err != nil {
return err
}
fmt.Println("---")
fmt.Println(string(data))
return nil
}
func exportHelmCredentials(ctx context.Context, kubeClient client.Client, source sourcev1.HelmRepository) error {
if source.Spec.SecretRef != nil {
namespacedName := types.NamespacedName{

View File

@@ -19,7 +19,6 @@ package main
import (
"context"
"fmt"
"github.com/fluxcd/pkg/untar"
"io/ioutil"
"net/http"
"os"
@@ -31,6 +30,8 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/krusty"
"github.com/fluxcd/pkg/untar"
)
var installCmd = &cobra.Command{
@@ -61,6 +62,7 @@ var (
installComponents []string
installRegistry string
installImagePullSecret string
installArch string
)
func init() {
@@ -74,14 +76,20 @@ func init() {
"list of components, accepts comma-separated values")
installCmd.Flags().StringVar(&installManifestsPath, "manifests", "",
"path to the manifest directory, dev only")
installCmd.Flags().StringVar(&installRegistry, "registry", "docker.io/fluxcd",
installCmd.Flags().StringVar(&installRegistry, "registry", "ghcr.io/fluxcd",
"container registry where the toolkit images are published")
installCmd.Flags().StringVar(&installImagePullSecret, "image-pull-secret", "",
"Kubernetes secret name used for pulling the toolkit images from a private registry")
installCmd.Flags().StringVar(&installArch, "arch", "amd64",
"arch can be amd64 or arm64")
rootCmd.AddCommand(installCmd)
}
func installCmdRun(cmd *cobra.Command, args []string) error {
if !utils.containsItemString(supportedArch, installArch) {
return fmt.Errorf("arch %s is not supported, can be %v", installArch, supportedArch)
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
@@ -103,7 +111,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
logger.Generatef("generating manifests")
}
if kustomizePath == "" {
err = genInstallManifests(installVersion, namespace, installComponents, installRegistry, installImagePullSecret, tmpDir)
err = genInstallManifests(installVersion, namespace, installComponents, installRegistry, installImagePullSecret, installArch, tmpDir)
if err != nil {
return fmt.Errorf("install failed: %w", err)
}
@@ -192,6 +200,7 @@ fieldSpecs:
var kustomizationTmpl = `---
{{- $eventsAddr := .EventsAddr }}
{{- $registry := .Registry }}
{{- $arch := .Arch }}
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: {{.Namespace}}
@@ -231,7 +240,11 @@ patchesJson6902:
images:
{{- range $i, $component := .Components }}
- name: fluxcd/{{$component}}
{{- if eq $arch "amd64" }}
newName: {{$registry}}/{{$component}}
{{- else }}
newName: {{$registry}}/{{$component}}-{{$arch}}
{{- end }}
{{- end }}
{{- end }}
`
@@ -253,7 +266,7 @@ spec:
template:
spec:
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/arch: {{.Arch}}
kubernetes.io/os: linux
{{- if .ImagePullSecret }}
imagePullSecrets:
@@ -295,7 +308,7 @@ func downloadManifests(version string, tmpDir string) error {
return nil
}
func genInstallManifests(version string, namespace string, components []string, registry, imagePullSecret, tmpDir string) error {
func genInstallManifests(version string, namespace string, components []string, registry, imagePullSecret, arch, tmpDir string) error {
eventsAddr := ""
if utils.containsItemString(components, defaultNotification) {
eventsAddr = fmt.Sprintf("http://%s/", defaultNotification)
@@ -308,6 +321,7 @@ func genInstallManifests(version string, namespace string, components []string,
EventsAddr string
Registry string
ImagePullSecret string
Arch string
}{
Version: version,
Namespace: namespace,
@@ -315,6 +329,7 @@ func genInstallManifests(version string, namespace string, components []string,
EventsAddr: eventsAddr,
Registry: registry,
ImagePullSecret: imagePullSecret,
Arch: arch,
}
if err := downloadManifests(version, tmpDir); err != nil {

View File

@@ -26,6 +26,8 @@ import (
"github.com/spf13/cobra/doc"
_ "k8s.io/client-go/plugin/pkg/client/auth"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
gotklog "github.com/fluxcd/toolkit/pkg/log"
)
@@ -104,10 +106,13 @@ var (
)
var (
defaultComponents = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
defaultVersion = "latest"
defaultNamespace = "gitops-system"
defaultNotification = "notification-controller"
defaultComponents = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
defaultVersion = "latest"
defaultNamespace = "gitops-system"
defaultNotification = "notification-controller"
supportedArch = []string{"arm64", "amd64"}
supportedDecryptionProviders = []string{"sops"}
supportedHelmChartSourceKinds = []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind}
)
func init() {

View File

@@ -9,10 +9,12 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
### Options
```
--arch string arch can be amd64 or arm64 (default "amd64")
--branch string default branch (for GitHub this must match the default branch setting for the organization) (default "master")
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
-h, --help help for bootstrap
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
--registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd")
-v, --version string toolkit version (default "latest")
```

View File

@@ -35,6 +35,9 @@ gotk bootstrap github [flags]
# Run bootstrap for a private repo hosted on GitHub Enterprise
gotk bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap github --owner=<organization> --repository=<repo name> --branch=main
```
### Options
@@ -54,11 +57,13 @@ gotk bootstrap github [flags]
### Options inherited from parent commands
```
--arch string arch can be amd64 or arm64 (default "amd64")
--branch string default branch (for GitHub this must match the default branch setting for the organization) (default "master")
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
--registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects
-v, --version string toolkit version (default "latest")

View File

@@ -32,6 +32,9 @@ gotk bootstrap gitlab [flags]
# Run bootstrap for a private repo hosted on a GitLab server
gotk bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main
```
### Options
@@ -51,11 +54,13 @@ gotk bootstrap gitlab [flags]
### Options inherited from parent commands
```
--arch string arch can be amd64 or arm64 (default "amd64")
--branch string default branch (for GitHub this must match the default branch setting for the organization) (default "master")
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--namespace string the namespace scope for this operation (default "gitops-system")
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
--registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects
-v, --version string toolkit version (default "latest")

View File

@@ -12,6 +12,7 @@ The create sub-commands generate sources and resources.
--export export in YAML format to stdout
-h, --help help for create
--interval duration source sync interval (default 1m0s)
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
```
### Options inherited from parent commands

View File

@@ -13,37 +13,41 @@ gotk create helmrelease [name] [flags]
### Examples
```
# Create a HelmRelease from a HelmRepository source
# Create a HelmRelease with a chart from a HelmRepository source
gotk create hr podinfo \
--interval=10m \
--release-name=podinfo \
--target-namespace=default \
--source=HelmRepository/podinfo \
--chart=podinfo \
--chart-version=">4.0.0"
# Create a HelmRelease from a GitRepository source
# Create a HelmRelease with a chart from a GitRepository source
gotk create hr podinfo \
--interval=10m \
--release-name=podinfo \
--target-namespace=default \
--source=GitRepository/podinfo \
--chart=./charts/podinfo
# Create a HelmRelease with values for a local YAML file
# Create a HelmRelease with values from a local YAML file
gotk create hr podinfo \
--source=HelmRepository/podinfo \
--chart=podinfo \
--values=./my-values.yaml
# Create a HelmRelease with a custom release name
gotk create hr podinfo \
--release-name=podinfo-dev
--source=HelmRepository/podinfo \
--chart=podinfo \
# Create a HelmRelease targeting another namespace than the resource
gotk create hr podinfo \
--target-namespace=default \
--source=HelmRepository/podinfo \
--chart=podinfo \
--chart-version=4.0.5 \
--values=./my-values.yaml
--chart=podinfo
# Create a HelmRelease definition on disk without applying it on the cluster
gotk create hr podinfo \
--target-namespace=default \
--source=HelmRepository/podinfo \
--chart=podinfo \
--chart-version=4.0.5 \
--values=./values.yaml \
--export > podinfo-release.yaml
@@ -53,10 +57,10 @@ gotk create helmrelease [name] [flags]
```
--chart string Helm chart name or path
--chart-version string Helm chart version, accepts semver range (ignored for charts from GitRepository sources)
--chart-version string Helm chart version, accepts a semver range (ignored for charts from GitRepository sources)
--depends-on stringArray HelmReleases that must be ready before this release can be installed
-h, --help help for helmrelease
--release-name string name used for the Helm release, defaults to a composition of '<target-namespace>-<hr-name>'
--release-name string name used for the Helm release, defaults to a composition of '[<target-namespace>-]<hr-name>'
--source string source that contains the chart (<kind>/<name>)
--target-namespace string namespace to install this release, defaults to the HelmRelease namespace
--values string local path to the values.yaml file
@@ -68,6 +72,7 @@ gotk create helmrelease [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -48,6 +48,8 @@ gotk create kustomization [name] [flags]
### Options
```
--decryption-provider string enables secrets decryption, provider can be 'sops'
--decryption-secret string set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption
--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)
@@ -66,6 +68,7 @@ gotk create kustomization [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -18,6 +18,7 @@ The create source sub-commands generate sources.
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -73,6 +73,7 @@ gotk create source git [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -53,6 +53,7 @@ gotk create source helm [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -31,13 +31,14 @@ gotk install [flags]
### Options
```
--arch string arch can be amd64 or arm64 (default "amd64")
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
--dry-run only print the object that would be applied
--export write the install manifests to stdout and exit
-h, --help help for install
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
--manifests string path to the manifest directory, dev only
--registry string container registry where the toolkit images are published (default "docker.io/fluxcd")
--registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd")
-v, --version string toolkit version (default "latest")
```

View File

@@ -19,17 +19,25 @@ export GITHUB_USER=<your-username>
## Install the toolkit CLI
To install the latest `gotk` release run:
To install the latest `gotk` release on MacOS and Linux using
[Homebrew](https://brew.sh/) run:
```sh
brew tap fluxcd/tap
brew install gotk
```
Or install `gotk` by downloading precompiled binaries using a Bash script:
```sh
curl -s https://toolkit.fluxcd.io/install.sh | sudo bash
```
The install script downloads the gotk binary to `/usr/local/bin`.
Binaries for macOS and Linux AMD64 are available for download on the
Binaries for macOS and Linux AMD64/ARM64 are available for download on the
[release page](https://github.com/fluxcd/toolkit/releases).
To configure your shell to load gotk completions add to your bash profile:
To configure your shell to load gotk completions add to your Bash profile:
```sh
# ~/.bashrc or ~/.bash_profile

View File

@@ -14,17 +14,28 @@ toolkit controllers installed on it.
Please see the [get started guide](../get-started/index.md)
or the [installation guide](installation.md).
## Define a Helm repository
## Define a chart source
To be able to deploy a Helm chart, the Helm chart repository has to be
known first to the source-controller, so that the `HelmRelease` can
reference to it.
To be able to release a Helm chart, the source that contains the chart
(either a `HelmRepository` or `GitRepository`) has to be known first to
the source-controller, so that the `HelmRelease` can reference to it.
A cluster administrator should register trusted sources by creating
`HelmRepository` resources in the `gitops-system` namespace.
By default, the source-controller watches for sources only in the
`gitops-system` namespace, this way cluster admins can prevent
untrusted sources from being registered by users.
the resources in the `gitops-system` namespace. By default, the
source-controller watches for sources only in the `gitops-system`
namespace, this way cluster admins can prevent untrusted sources from
being registered by users.
### Helm repository
Helm repositories are the recommended source to retrieve Helm charts
from, as they are lightweight in processing and make it possible to
configure a semantic version selector for the chart version that should
be released.
They can be declared by creating a `HelmRepository` resource, the
source-controller will fetch the Helm repository index for this
resource on an interval and expose it as an artifact:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1alpha1
@@ -48,11 +59,73 @@ The `url` can be any HTTP/S Helm repository URL.
HTTP/S basic and TLS authentication can be configured for private
Helm repositories. See the [`HelmRepository` CRD docs](../components/source/helmrepositories.md)
for more details.
### Git repository
Charts from Git repositories can be released by declaring a
`GitRepository`, the source-controller will fetch the contents
of the repository on an interval and expose it as an artifact.
The source-controller can build and expose Helm charts as
artifacts from the contents of the `GitRepository` artifact
(more about this later on in the guide).
There are two caveats you should be aware of:
* To make the source-controller produce a new chart artifact,
the `version` in the `Chart.yaml` of the chart **must** be
bumped.
* Chart dependencies **must** be committed to Git, as the
source-controller does not attempt to download them. This
limitation may be removed in a future release.
An example `GitRepository`:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1alpha1
kind: GitRepository
metadata:
name: podinfo
namespace: gitops-system
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
ref:
branch: master
ignore: |
# exclude all
/*
# include charts directory
!/charts/
```
The `interval` defines at which interval the Git repository contents
are fetched, and should be at least `1m`. Setting this to a higher
value means newer chart versions will be detected at a slower pace,
a push-based fetch can be introduced using [webhook receivers](webhook-receivers.md)
The `url` can be any HTTP/S or SSH address (the latter requiring
authentication).
The `ref` defines the checkout strategy, and is set to follow the
`master` branch in the above example. For other strategies like
tags or commits, see the [`GitRepository` CRD docs](../components/source/gitrepositories.md).
The `ignore` defines file and folder exclusion for the
artifact produced, and follows the [`.gitignore` pattern
format](https://git-scm.com/docs/gitignore#_pattern_format).
The above example only includes the `charts` directory of the
repository and omits all other files.
!!! hint "Authentication"
HTTP/S basic and SSH authentication can be configured for private
Git repositories. See the [`GitRepository` CRD docs](../components/source/gitrepositories.md)
for more details.
## Define a Helm release
With the `HelmRepository` created, define a new `HelmRelease` to deploy
the Helm chart from the repository:
With the chart source created, define a new `HelmRelease` to release
the Helm chart:
```yaml
apiVersion: helm.toolkit.fluxcd.io/v2alpha1
@@ -64,10 +137,10 @@ spec:
interval: 5m
chart:
spec:
chart: podinfo
chart: <name|path>
version: '4.0.x'
sourceRef:
kind: HelmRepository
kind: <HelmRepository|GitRepository>
name: podinfo
namespace: gitops-system
interval: 1m
@@ -75,19 +148,25 @@ spec:
replicaCount: 2
```
The `chart.spec.chart` is the name of the chart as made available by
the Helm repository, and may not include any aliases.
The `chart.spec.version` can be a fixed semver, or any semver range
(i.e. `>=4.0.0 <5.0.0`).
The `chart.spec` values are used by the helm-controller as a template
to create a new `HelmChart` resource in the same namespace as the
`sourceRef`. The source-controller will then lookup the chart in the
artifact of the referenced `HelmRepository`, fetch the chart, and make
it available as a `HelmChart` artifact to be used by the
artifact of the referenced source, and either fetch the chart for a
`HelmRepository`, or build it from a `GitRepository`. It will then
make it available as a `HelmChart` artifact to be used by the
helm-controller.
The `chart.spec.chart` can either contain:
* The name of the chart as made available by the `HelmRepository`
(without any aliases), for example: `podinfo`
* The relative path the chart can be found at in the `GitRepository`,
for example: `./charts/podinfo`
The `chart.spec.version` can be a fixed semver, or any semver range
(i.e. `>=4.0.0 <5.0.0`). It is ignored for `HelmRelease` resources
that reference a `GitRepository` source.
!!! hint "Advanced configuration"
The `HelmRelease` offers an extensive set of configurable flags
for finer grain control over how Helm actions are performed.

View File

@@ -8,14 +8,25 @@ to manage one or more Kubernetes clusters.
You will need a Kubernetes cluster version **1.16** or newer
and kubectl version **1.18** or newer.
Install the toolkit CLI with:
## Install the toolkit CLI
With Homebrew:
```sh
brew tap fluxcd/tap
brew install gotk
```
With Bash:
```sh
curl -s https://toolkit.fluxcd.io/install.sh | sudo bash
# enable completions in ~/.bash_profile
. <(gotk completion)
```
The install script downloads the gotk binary to `/usr/local/bin`.
Binaries for macOS and Linux AMD64 are available for download on the
Binaries for macOS and Linux AMD64/ARM64 are available for download on the
[release page](https://github.com/fluxcd/toolkit/releases).
Verify that your cluster satisfies the prerequisites with:
@@ -47,6 +58,10 @@ gotk bootstrap <GIT-PROVIDER> \
--version=latest
```
!!! hint "ARM64"
When deploying to a Kubernetes cluster with ARM 64-bit architecture,
you can use `--arch=arm64` to pull the linux/arm64 toolkit container images.
If you wish to install a specific version, use the toolkit
[release tag](https://github.com/fluxcd/toolkit/releases) e.g. `--version=v0.0.14`.
@@ -64,6 +79,10 @@ cluster e.g. `staging-cluster` and `production-cluster`:
└── gitops-system
```
!!! hint "Change the default branch"
If you wish to change the branch to something else than master, create the repository manually,
push a branch to origin and then use `gotk bootstrap <GIT-PROVIDER> --branch=your-branch`.
### GitHub and GitHub Enterprise
Generate a [personal access token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line)
@@ -169,16 +188,17 @@ Generate the toolkit manifests with:
```sh
gotk install --version=latest \
--arch=amd64 \ # on ARM64/AARCH64 clusters use --arch=arm64
--export > ./my-cluster/gitops-system/toolkit-components.yaml
```
If your cluster must pull images from a private container registry, first you should pull
the toolkit images from Docker Hub and push them to your registry, for example:
the toolkit images from GitHub Container Registry and push them to your registry, for example:
```sh
docker pull fluxcd/source-controller:v0.0.7
docker tag fluxcd/source-controller:v0.0.7 registry.internal/fluxcd/source-controller:v0.0.7
docker push registry.internal/fluxcd/source-controller:v0.0.7
docker pull ghcr.io/fluxcd/source-controller:v0.0.14
docker tag ghcr.io/fluxcd/source-controller:v0.0.14 registry.internal/fluxcd/source-controller:v0.0.14
docker push registry.internal/fluxcd/source-controller:v0.0.14
```
Create the pull secret in the `gitops-system` namespace:
@@ -324,9 +344,9 @@ gotk create helmrelease sealed-secrets \
--interval=1h \
--release-name=sealed-secrets \
--target-namespace=gitops-system \
--source=stable \
--chart-name=sealed-secrets \
--chart-version="^1.10.0"
--source=HelmRepository/stable \
--chart=sealed-secrets \
--chart-version="1.10.x"
```
### Monitoring with Prometheus and Grafana

166
docs/guides/mozilla-sops.md Normal file
View File

@@ -0,0 +1,166 @@
# Manage Kubernetes secrets with Mozilla SOPS
In order to store secrets safely in a public or private Git repository, you can use
Mozilla's [SOPS](https://github.com/mozilla/sops) CLI to encrypt
Kubernetes secrets with OpenPGP, AWS KMS, GCP KMS and Azure Key Vault.
## Prerequisites
To follow this guide you'll need a Kubernetes cluster with the GitOps
toolkit controllers installed on it.
Please see the [get started guide](../get-started/index.md)
or the [installation guide](installation.md).
Install [gnupg](https://www.gnupg.org/) and [sops](https://github.com/mozilla/sops):
```sh
brew install gnupg sops
```
## Generate a GPG key
Generate a GPG key with OpenPGP without specifying a passphrase:
```console
$ gpg --full-generate-key
Real name: stefanprodan
Email address: stefanprodan@users.noreply.github.com
Comment:
You selected this USER-ID:
"stefanprodan <stefanprodan@users.noreply.github.com>"
```
Retrieve the GPG key ID (second row of the sec column):
```console
$ gpg --list-secret-keys stefanprodan@users.noreply.github.com
sec rsa3072 2020-09-06 [SC]
1F3D1CED2F865F5E59CA564553241F147E7C5FA4
```
Export the public and private keypair from your local GPG keyring and
create a Kubernetes secret named `sops-gpg` in the `gitops-system` namespace:
```sh
gpg --export-secret-keys \
--armor 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 |
kubectl create secret generic sops-gpg \
--namespace=gitops-system \
--from-file=sops.asc=/dev/stdin
```
## Encrypt secrets
Generate a Kubernetes secret manifest with kubectl:
```sh
kubectl -n default create secret generic basic-auth \
--from-literal=user=admin \
--from-literal=password=change-me \
--dry-run=client \
-o yaml > basic-auth.yaml
```
Encrypt the secret with sops using your GPG key:
```sh
sops --encrypt \
--pgp=1F3D1CED2F865F5E59CA564553241F147E7C5FA4 \
--encrypted-regex '^(data|stringData)$' \
--in-place basic-auth.yaml
```
!!! hint
Note that you should encrypt only the `data` section. Encrypting the Kubernetes
secret metadata, kind or apiVersion is not supported by kustomize-controller.
You can now commit the encrypted secret to your Git repository.
## Configure secrets decryption
Registry the Git repository on your cluster:
```sh
gotk create source git my-secrets \
--url=https://github.com/my-org/my-secrets
```
Create a kustomization for reconciling the secrets on the cluster:
```sh
gotk create kustomization my-secrets \
--source=my-secrets \
--prune=true \
--interval=10m \
--decryption-provider=sops \
--decryption-secret=sops-gpg
```
Note that the `sops-gpg` can contain more than one key, sops will try to decrypt the
secrets by iterating over all the private keys until it finds one that works.
!!! hint KMS
When using AWS/GCP KMS or Azure Key Vault, you'll have to bind an IAM Role
with read access to the KMS keys to the `default` service account of the
`gitops-system` namespace for kustomize-controller to be able to fetch
keys from KMS.
## GitOps workflow
A cluster admin should create the Kubernetes secret with the PGP keys on each cluster and
add the GitRepository/Kustomization manifests to the fleet repository.
Git repository manifest:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1alpha1
kind: GitRepository
metadata:
name: my-secrets
namespace: gitops-system
spec:
interval: 1m
url: https://github.com/my-org/my-secrets
```
Kustomization manifest:
```yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1alpha1
kind: Kustomization
metadata:
name: my-secrets
namespace: gitops-system
spec:
interval: 10m0s
sourceRef:
kind: GitRepository
name: my-secrets
path: ./
prune: true
decryption:
provider: sops
secretRef:
name: sops-gpg
```
!!! hint
You can generate the above manifests using `gotk create <kind> --export > manifest.yaml`.
Assuming a team member wants to deploy an application that needs to connect
to a database using a username and password, they'll be doing the following:
* create a Kubernetes Secret manifest locally with the db credentials e.g. `db-auth.yaml`
* encrypt the secret `data` field with sops
* create a Kubernetes Deployment manifest for the app e.g. `app-deployment.yaml`
* add the Secret to the Deployment manifest as a [volume mount or env var](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets)
* commit the manifests `db-auth.yaml` and `app-deployment.yaml` to a Git repository that's being synced by the GitOps toolkit controllers
Once the manifests have been pushed to the Git repository, the following happens:
* source-controller pulls the changes from Git
* kustomize-controller loads the GPG keys from the `sops-pgp` secret
* kustomize-controller decrypts the Kubernetes secrets with sops and applies them on the cluster
* kubelet creates the pods and mounts the secret as a volume or env variable inside the app container

View File

@@ -50,13 +50,13 @@ gotk create helmrelease sealed-secrets \
--interval=1h \
--release-name=sealed-secrets \
--target-namespace=gitops-system \
--source=stable \
--chart-name=sealed-secrets \
--chart-version="^1.10.0"
--source=HelmRepository/stable \
--chart=sealed-secrets \
--chart-version="1.10.x"
```
With chart version `^1.10.0` we configure helm-controller to automatically upgrade the release
when a new chart version is fetch by source-controller.
With chart version `1.10.x` we configure helm-controller to automatically upgrade the release
when a new chart patch version is fetched by source-controller.
At startup, the sealed-secrets controller generates a 4096-bit RSA key pair and
persists the private and public keys as Kubernetes secrets in the `gitops-system` namespace.
@@ -102,7 +102,7 @@ kubectl apply -f basic-auth-sealed.yaml
Verify that the sealed-secrets controller has created the `basic-auth` Kubernetes Secret:
```console
$ kubectl -n default get secrets basic-auth
$ kubectl -n default get secrets basic-auth
NAME TYPE DATA AGE
basic-auth Opaque 2 1m43s

8
go.mod
View File

@@ -4,12 +4,12 @@ go 1.14
require (
github.com/blang/semver v3.5.1+incompatible
github.com/fluxcd/helm-controller/api v0.0.6
github.com/fluxcd/kustomize-controller/api v0.0.8
github.com/fluxcd/pkg/git v0.0.6
github.com/fluxcd/helm-controller/api v0.0.7
github.com/fluxcd/kustomize-controller/api v0.0.10
github.com/fluxcd/pkg/git v0.0.7
github.com/fluxcd/pkg/ssh v0.0.5
github.com/fluxcd/pkg/untar v0.0.5
github.com/fluxcd/source-controller/api v0.0.13
github.com/fluxcd/source-controller/api v0.0.14
github.com/manifoldco/promptui v0.7.0
github.com/spf13/cobra v1.0.0
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect

33
go.sum
View File

@@ -111,18 +111,18 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fluxcd/helm-controller/api v0.0.6 h1:EpP1/cYClFrZqaw4B2mZ/qxTSDmvxJxj+VYZZR1XaTI=
github.com/fluxcd/helm-controller/api v0.0.6/go.mod h1:KlzwTkpphQxulgWBwCl/uxfBU0QxK/X+w4YcJqGy/1c=
github.com/fluxcd/kustomize-controller/api v0.0.8 h1:Yi5/MZuS2jXiRV73fuUkBCyRTuG0yx2HJTpWZaM+WHA=
github.com/fluxcd/kustomize-controller/api v0.0.8/go.mod h1:c4035rZrt2p3RExpLe64ASVEvePm7FjiY4PzHKpRJXI=
github.com/fluxcd/pkg/git v0.0.6 h1:4qktw8M3zj98MAs4ny6qSi36sYvTiI1czif5FqlQl4o=
github.com/fluxcd/pkg/git v0.0.6/go.mod h1:9AI9yPkb2ruIcE70moVG3WhunA2/RAMJPc3rtoH8QFE=
github.com/fluxcd/helm-controller/api v0.0.7 h1:aidjXvcklClH8omhYqiKswZ+MS6t8knOpUacsuESue8=
github.com/fluxcd/helm-controller/api v0.0.7/go.mod h1:KlzwTkpphQxulgWBwCl/uxfBU0QxK/X+w4YcJqGy/1c=
github.com/fluxcd/kustomize-controller/api v0.0.10 h1:dhkTOg3LzNQwRL+lO0YlzOP7AhdpZdghUQNXYhvfiYU=
github.com/fluxcd/kustomize-controller/api v0.0.10/go.mod h1:88m3p6xY3J2pjh5OsL3ANy7PkyA93KiqAJE58JMQyoc=
github.com/fluxcd/pkg/git v0.0.7 h1:tFSYPy7tcIYfOt8H5EUERXIRz7fk0id302oQZde1NtU=
github.com/fluxcd/pkg/git v0.0.7/go.mod h1:5Vu92x6Q3CpxDUllmB69kAkVY5jAtPpXcY2TSZ/oCJI=
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
github.com/fluxcd/pkg/ssh v0.0.5/go.mod h1:7jXPdXZpc0ttMNz2kD9QuMi3RNn/e0DOFbj0Tij/+Hs=
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
github.com/fluxcd/source-controller/api v0.0.13 h1:rf0uZ20OAN+yJVs0uHJUhw3n3ci9ZyjaLqt5Jt/5K9A=
github.com/fluxcd/source-controller/api v0.0.13/go.mod h1:PUe+EYQ/s+KPnz2iOCgdf+L6clM0SWkyvdXIpbfpkQE=
github.com/fluxcd/source-controller/api v0.0.14 h1:iNG6AGnr44z4T6F0JC2M82ekyxzJ29c3m+DVC7FwSHQ=
github.com/fluxcd/source-controller/api v0.0.14/go.mod h1:PUe+EYQ/s+KPnz2iOCgdf+L6clM0SWkyvdXIpbfpkQE=
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/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -265,8 +265,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
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=
github.com/google/go-github/v32 v32.0.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
@@ -726,35 +726,24 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
k8s.io/api v0.18.4 h1:8x49nBRxuXGUlDlwlWd3RMY1SayZrzFfxea3UZSkFw4=
k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4=
k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI=
k8s.io/api v0.18.8 h1:aIKUzJPb96f3fKec2lxtY7acZC9gQNDLVhfSGpxBAC4=
k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY=
k8s.io/apiextensions-apiserver v0.18.4 h1:Y3HGERmS8t9u12YNUFoOISqefaoGRuTc43AYCLzWmWE=
k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio=
k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKizADfvUM/SS/M=
k8s.io/apiextensions-apiserver v0.18.8 h1:pkqYPKTHa0/3lYwH7201RpF9eFm0lmZDFBNzhN+k/sA=
k8s.io/apiextensions-apiserver v0.18.8/go.mod h1:7f4ySEkkvifIr4+BRrRWriKKIJjPyg9mb/p63dJKnlM=
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
k8s.io/apimachinery v0.18.4 h1:ST2beySjhqwJoIFk6p7Hp5v5O0hYY6Gngq/gUYXTPIA=
k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/apimachinery v0.18.8 h1:jimPrycCqgx2QPearX3to1JePz7wSbVLq+7PdBTTwQ0=
k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig=
k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
k8s.io/apiserver v0.18.6/go.mod h1:Zt2XvTHuaZjBz6EFYzpp+X4hTmgWGy8AthNVnTdm3Wg=
k8s.io/apiserver v0.18.8/go.mod h1:12u5FuGql8Cc497ORNj79rhPdiXQC4bf53X/skR/1YM=
k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
k8s.io/client-go v0.18.4 h1:un55V1Q/B3JO3A76eS0kUSywgGK/WR3BQ8fHQjNa6Zc=
k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g=
k8s.io/client-go v0.18.6/go.mod h1:/fwtGLjYMS1MaM5oi+eXhKwG+1UHidUEXRh6cNsdO0Q=
k8s.io/client-go v0.18.8 h1:SdbLpIxk5j5YbFr1b7fq8S7mDgDjYmUxSbszyoesoDM=
k8s.io/client-go v0.18.8/go.mod h1:HqFqMllQ5NnQJNwjro9k5zMyfhZlOwpuTLVrxjkYSxU=
k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/code-generator v0.18.6/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/code-generator v0.18.8/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk=
k8s.io/component-base v0.18.6/go.mod h1:knSVsibPR5K6EW2XOjEHik6sdU5nCvKMrzMt2D4In14=
k8s.io/component-base v0.18.8/go.mod h1:00frPRDas29rx58pPCxNkhUfPbwajlyyvu8ruNgSErU=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
@@ -776,8 +765,6 @@ mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIa
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
sigs.k8s.io/controller-runtime v0.6.1 h1:LcK2+nk0kmaOnKGN+vBcWHqY5WDJNJNB/c5pW+sU8fc=
sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
sigs.k8s.io/controller-runtime v0.6.2 h1:jkAnfdTYBpFwlmBn3pS5HFO06SfxvnTZ1p5PeEF/zAA=
sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E=
sigs.k8s.io/kustomize/api v0.5.1 h1:iHGTs5LcnJGqHstUSxWD/kX6XZgmd82x79LLlZwDU0I=

View File

@@ -42,6 +42,9 @@ setup_verify_arch() {
ARCH=$(uname -m)
fi
case ${ARCH} in
arm64)
ARCH=arm64
;;
amd64)
ARCH=amd64
;;

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/helm-controller/config//crd?ref=v0.0.6
- github.com/fluxcd/helm-controller/config//manager?ref=v0.0.6
- github.com/fluxcd/helm-controller/config//crd?ref=v0.0.7
- github.com/fluxcd/helm-controller/config//manager?ref=v0.0.7
patchesJson6902:
- target:
group: apps

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/kustomize-controller/config//crd?ref=v0.0.8
- github.com/fluxcd/kustomize-controller/config//manager?ref=v0.0.8
- github.com/fluxcd/kustomize-controller/config//crd?ref=v0.0.10
- github.com/fluxcd/kustomize-controller/config//manager?ref=v0.0.10
patchesJson6902:
- target:
group: apps

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/source-controller/config//crd?ref=v0.0.13
- github.com/fluxcd/source-controller/config//manager?ref=v0.0.13
- github.com/fluxcd/source-controller/config//crd?ref=v0.0.14
- github.com/fluxcd/source-controller/config//manager?ref=v0.0.14
patchesJson6902:
- target:
group: apps

View File

@@ -50,6 +50,7 @@ nav:
- Setup Notifications: guides/notifications.md
- Setup Webhook Receivers: guides/webhook-receivers.md
- Sealed Secrets: guides/sealed-secrets.md
- Mozilla SOPS: guides/mozilla-sops.md
- Toolkit Components:
- Source Controller:
- Overview: components/source/controller.md