From bd2994f9ab1d009d13b3c6f033bc6c4c7c9bdade Mon Sep 17 00:00:00 2001
From: stefanprodan <stefan.prodan@gmail.com>
Date: Wed, 23 Sep 2020 16:44:31 +0300
Subject: [PATCH] Add support for Bucket sources to Kustomizations/HRs

---
 cmd/gotk/create_helmrelease.go        |  6 ++++++
 cmd/gotk/create_kustomization.go      | 31 +++++++++++++++++----------
 cmd/gotk/main.go                      | 19 ++++++++--------
 cmd/gotk/reconcile_helmrelease.go     |  6 ++++--
 cmd/gotk/reconcile_kustomization.go   |  8 ++++++-
 cmd/gotk/reconcile_source_bucket.go   |  4 ++--
 cmd/gotk/reconcile_source_git.go      |  5 ++---
 cmd/gotk/reconcile_source_helm.go     |  4 ++--
 docs/cmd/gotk_create_helmrelease.md   |  6 ++++++
 docs/cmd/gotk_create_kustomization.md | 14 +++++-------
 10 files changed, 64 insertions(+), 39 deletions(-)

diff --git a/cmd/gotk/create_helmrelease.go b/cmd/gotk/create_helmrelease.go
index 2b6a61f5..d78278be 100644
--- a/cmd/gotk/create_helmrelease.go
+++ b/cmd/gotk/create_helmrelease.go
@@ -55,6 +55,12 @@ var createHelmReleaseCmd = &cobra.Command{
     --source=GitRepository/podinfo \
     --chart=./charts/podinfo
 
+  # Create a HelmRelease with a chart from a Bucket source
+  gotk create hr podinfo \
+    --interval=10m \
+    --source=Bucket/podinfo \
+    --chart=./charts/podinfo
+
   # Create a HelmRelease with values from a local YAML file
   gotk create hr podinfo \
     --source=HelmRepository/podinfo \
diff --git a/cmd/gotk/create_kustomization.go b/cmd/gotk/create_kustomization.go
index e5898692..c6e884e5 100644
--- a/cmd/gotk/create_kustomization.go
+++ b/cmd/gotk/create_kustomization.go
@@ -60,15 +60,11 @@ var createKsCmd = &cobra.Command{
     --interval=5m \
     --validation=client
 
-  # Create a Kustomization resource that runs under a service account
-  gotk create kustomization webapp \
-    --source=webapp \
-    --path="./deploy/overlays/staging" \
+  # Create a Kustomization resource that references a Bucket
+  gotk create kustomization secrets \
+    --source=Bucket/secrets \
     --prune=true \
-    --interval=5m \
-    --validation=client \
-    --sa-name=reconclier \
-    --sa-namespace=staging
+    --interval=5m
 `,
 	RunE: createKsCmdRun,
 }
@@ -88,7 +84,8 @@ var (
 )
 
 func init() {
-	createKsCmd.Flags().StringVar(&ksSource, "source", "", "GitRepository name")
+	createKsCmd.Flags().StringVar(&ksSource, "source", "",
+		"source that contains the Kubernetes manifests, format '<kind>/<name>' where kind can be GitRepository or Bucket, if kind is not specified it defaults to GitRepository")
 	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>'")
@@ -111,6 +108,18 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
 	if ksSource == "" {
 		return fmt.Errorf("source is required")
 	}
+
+	ksSourceKind := sourcev1.GitRepositoryKind
+	ksSourceName := ksSource
+	ksSourceElements := strings.Split(ksSource, "/")
+	if len(ksSourceElements) == 2 {
+		ksSourceKind, ksSourceName = ksSourceElements[0], ksSourceElements[1]
+		if !utils.containsItemString(supportedKustomizationSourceKinds, ksSourceKind) {
+			return fmt.Errorf("source kind %s is not supported, can be %v",
+				ksSourceKind, supportedKustomizationSourceKinds)
+		}
+	}
+
 	if ksPath == "" {
 		return fmt.Errorf("path is required")
 	}
@@ -141,8 +150,8 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
 			Path:  ksPath,
 			Prune: ksPrune,
 			SourceRef: kustomizev1.CrossNamespaceSourceReference{
-				Kind: sourcev1.GitRepositoryKind,
-				Name: ksSource,
+				Kind: ksSourceKind,
+				Name: ksSourceName,
 			},
 			Suspend:    false,
 			Validation: ksValidation,
diff --git a/cmd/gotk/main.go b/cmd/gotk/main.go
index 7087b818..1e24926d 100644
--- a/cmd/gotk/main.go
+++ b/cmd/gotk/main.go
@@ -106,15 +106,16 @@ var (
 )
 
 var (
-	defaultComponents              = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
-	defaultVersion                 = "latest"
-	defaultNamespace               = "gitops-system"
-	defaultNotification            = "notification-controller"
-	supportedLogLevels             = []string{"debug", "info", "error"}
-	supportedArch                  = []string{"amd64", "arm", "arm64"}
-	supportedDecryptionProviders   = []string{"sops"}
-	supportedHelmChartSourceKinds  = []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind}
-	supportedSourceBucketProviders = []string{sourcev1.GenericBucketProvider, sourcev1.AmazonBucketProvider}
+	defaultComponents                 = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
+	defaultVersion                    = "latest"
+	defaultNamespace                  = "gitops-system"
+	defaultNotification               = "notification-controller"
+	supportedLogLevels                = []string{"debug", "info", "error"}
+	supportedArch                     = []string{"amd64", "arm", "arm64"}
+	supportedDecryptionProviders      = []string{"sops"}
+	supportedKustomizationSourceKinds = []string{sourcev1.GitRepositoryKind, sourcev1.BucketKind}
+	supportedHelmChartSourceKinds     = []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind, sourcev1.BucketKind}
+	supportedSourceBucketProviders    = []string{sourcev1.GenericBucketProvider, sourcev1.AmazonBucketProvider}
 )
 
 func init() {
diff --git a/cmd/gotk/reconcile_helmrelease.go b/cmd/gotk/reconcile_helmrelease.go
index 5bce49bf..06083b0b 100644
--- a/cmd/gotk/reconcile_helmrelease.go
+++ b/cmd/gotk/reconcile_helmrelease.go
@@ -85,9 +85,11 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error {
 	if syncHrWithSource {
 		switch helmRelease.Spec.Chart.Spec.SourceRef.Kind {
 		case sourcev1.HelmRepositoryKind:
-			err = syncSourceHelmCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
+			err = reconcileSourceHelmCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
 		case sourcev1.GitRepositoryKind:
-			err = syncSourceGitCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
+			err = reconcileSourceGitCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
+		case sourcev1.BucketKind:
+			err = reconcileSourceBucketCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name})
 		}
 		if err != nil {
 			return err
diff --git a/cmd/gotk/reconcile_kustomization.go b/cmd/gotk/reconcile_kustomization.go
index 3dd5aa9b..07ff6a04 100644
--- a/cmd/gotk/reconcile_kustomization.go
+++ b/cmd/gotk/reconcile_kustomization.go
@@ -27,6 +27,7 @@ import (
 
 	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
 	consts "github.com/fluxcd/pkg/runtime"
+	sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
 )
 
 var reconcileKsCmd = &cobra.Command{
@@ -80,7 +81,12 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error {
 	}
 
 	if syncKsWithSource {
-		err := syncSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
+		switch kustomization.Spec.SourceRef.Kind {
+		case sourcev1.GitRepositoryKind:
+			err = reconcileSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
+		case sourcev1.BucketKind:
+			err = reconcileSourceBucketCmdRun(nil, []string{kustomization.Spec.SourceRef.Name})
+		}
 		if err != nil {
 			return err
 		}
diff --git a/cmd/gotk/reconcile_source_bucket.go b/cmd/gotk/reconcile_source_bucket.go
index fb4fbbbf..15b33e2a 100644
--- a/cmd/gotk/reconcile_source_bucket.go
+++ b/cmd/gotk/reconcile_source_bucket.go
@@ -38,14 +38,14 @@ var reconcileSourceBucketCmd = &cobra.Command{
 	Example: `  # Trigger a reconciliation for an existing source
   gotk reconcile source bucket podinfo
 `,
-	RunE: syncSourceBucketCmdRun,
+	RunE: reconcileSourceBucketCmdRun,
 }
 
 func init() {
 	reconcileSourceCmd.AddCommand(reconcileSourceBucketCmd)
 }
 
-func syncSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
+func reconcileSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
 	if len(args) < 1 {
 		return fmt.Errorf("source name is required")
 	}
diff --git a/cmd/gotk/reconcile_source_git.go b/cmd/gotk/reconcile_source_git.go
index 934c6e1c..7f2af513 100644
--- a/cmd/gotk/reconcile_source_git.go
+++ b/cmd/gotk/reconcile_source_git.go
@@ -19,7 +19,6 @@ package main
 import (
 	"context"
 	"fmt"
-
 	"time"
 
 	"github.com/spf13/cobra"
@@ -37,14 +36,14 @@ var reconcileSourceGitCmd = &cobra.Command{
 	Example: `  # Trigger a git pull for an existing source
   gotk reconcile source git podinfo
 `,
-	RunE: syncSourceGitCmdRun,
+	RunE: reconcileSourceGitCmdRun,
 }
 
 func init() {
 	reconcileSourceCmd.AddCommand(reconcileSourceGitCmd)
 }
 
-func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error {
+func reconcileSourceGitCmdRun(cmd *cobra.Command, args []string) error {
 	if len(args) < 1 {
 		return fmt.Errorf("source name is required")
 	}
diff --git a/cmd/gotk/reconcile_source_helm.go b/cmd/gotk/reconcile_source_helm.go
index 510da6f8..4e6fdac7 100644
--- a/cmd/gotk/reconcile_source_helm.go
+++ b/cmd/gotk/reconcile_source_helm.go
@@ -38,14 +38,14 @@ var reconcileSourceHelmCmd = &cobra.Command{
 	Example: `  # Trigger a reconciliation for an existing source
   gotk reconcile source helm podinfo
 `,
-	RunE: syncSourceHelmCmdRun,
+	RunE: reconcileSourceHelmCmdRun,
 }
 
 func init() {
 	reconcileSourceCmd.AddCommand(reconcileSourceHelmCmd)
 }
 
-func syncSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
+func reconcileSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
 	if len(args) < 1 {
 		return fmt.Errorf("source name is required")
 	}
diff --git a/docs/cmd/gotk_create_helmrelease.md b/docs/cmd/gotk_create_helmrelease.md
index 09e9803a..052a2c30 100644
--- a/docs/cmd/gotk_create_helmrelease.md
+++ b/docs/cmd/gotk_create_helmrelease.md
@@ -26,6 +26,12 @@ gotk create helmrelease [name] [flags]
     --source=GitRepository/podinfo \
     --chart=./charts/podinfo
 
+  # Create a HelmRelease with a chart from a Bucket source
+  gotk create hr podinfo \
+    --interval=10m \
+    --source=Bucket/podinfo \
+    --chart=./charts/podinfo
+
   # Create a HelmRelease with values from a local YAML file
   gotk create hr podinfo \
     --source=HelmRepository/podinfo \
diff --git a/docs/cmd/gotk_create_kustomization.md b/docs/cmd/gotk_create_kustomization.md
index 436cc329..9792283b 100644
--- a/docs/cmd/gotk_create_kustomization.md
+++ b/docs/cmd/gotk_create_kustomization.md
@@ -33,15 +33,11 @@ gotk create kustomization [name] [flags]
     --interval=5m \
     --validation=client
 
-  # Create a Kustomization resource that runs under a service account
-  gotk create kustomization webapp \
-    --source=webapp \
-    --path="./deploy/overlays/staging" \
+  # Create a Kustomization resource that references a Bucket
+  gotk create kustomization secrets \
+    --source=Bucket/secrets \
     --prune=true \
-    --interval=5m \
-    --validation=client \
-    --sa-name=reconclier \
-    --sa-namespace=staging
+    --interval=5m
 
 ```
 
@@ -58,7 +54,7 @@ gotk create kustomization [name] [flags]
       --prune                           enable garbage collection
       --sa-name string                  service account name
       --sa-namespace string             service account namespace
-      --source string                   GitRepository name
+      --source string                   source that contains the Kubernetes manifests, format '<kind>/<name>' where kind can be GitRepository or Bucket, if kind is not specified it defaults to GitRepository
       --validation string               validate the manifests before applying them on the cluster, can be 'client' or 'server'
 ```
 
-- 
GitLab