From 998b763cf955ff47451a5ada64de8be223a9bee8 Mon Sep 17 00:00:00 2001
From: Stefan Prodan <stefan.prodan@gmail.com>
Date: Thu, 2 Jun 2022 16:10:31 +0300
Subject: [PATCH] Add `--kubeconfig-secret-ref` to `flux create ks|hr` Allow
 specifying the name of the Kubernetes Secret that contains a key with the
 kubeconfig file for connecting to a remote cluster.

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
---
 cmd/flux/.create_helmrelease.go.swp | Bin 16384 -> 0 bytes
 cmd/flux/create_helmrelease.go      |  36 +++++++++++-------
 cmd/flux/create_kustomization.go    |  57 ++++++++++++++++------------
 3 files changed, 56 insertions(+), 37 deletions(-)
 delete mode 100644 cmd/flux/.create_helmrelease.go.swp

diff --git a/cmd/flux/.create_helmrelease.go.swp b/cmd/flux/.create_helmrelease.go.swp
deleted file mode 100644
index d42c707c4f43f19c29f11e07724beb5f80e304ef..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 16384
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
HX(Ig>3(~gr

diff --git a/cmd/flux/create_helmrelease.go b/cmd/flux/create_helmrelease.go
index 5a5f2c84..b4fdcdf1 100644
--- a/cmd/flux/create_helmrelease.go
+++ b/cmd/flux/create_helmrelease.go
@@ -109,19 +109,20 @@ var createHelmReleaseCmd = &cobra.Command{
 }
 
 type helmReleaseFlags struct {
-	name              string
-	source            flags.HelmChartSource
-	dependsOn         []string
-	chart             string
-	chartVersion      string
-	targetNamespace   string
-	createNamespace   bool
-	valuesFiles       []string
-	valuesFrom        flags.HelmReleaseValuesFrom
-	saName            string
-	crds              flags.CRDsPolicy
-	reconcileStrategy string
-	chartInterval     time.Duration
+	name                string
+	source              flags.HelmChartSource
+	dependsOn           []string
+	chart               string
+	chartVersion        string
+	targetNamespace     string
+	createNamespace     bool
+	valuesFiles         []string
+	valuesFrom          flags.HelmReleaseValuesFrom
+	saName              string
+	crds                flags.CRDsPolicy
+	reconcileStrategy   string
+	chartInterval       time.Duration
+	kubeConfigSecretRef string
 }
 
 var helmReleaseArgs helmReleaseFlags
@@ -140,6 +141,7 @@ func init() {
 	createHelmReleaseCmd.Flags().StringSliceVar(&helmReleaseArgs.valuesFiles, "values", nil, "local path to values.yaml files, also accepts comma-separated values")
 	createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.valuesFrom, "values-from", helmReleaseArgs.valuesFrom.Description())
 	createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.crds, "crds", helmReleaseArgs.crds.Description())
+	createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.kubeConfigSecretRef, "kubeconfig-secret-ref", "", "the name of the Kubernetes Secret that contains a key with the kubeconfig file for connecting to a remote cluster")
 	createCmd.AddCommand(createHelmReleaseCmd)
 }
 
@@ -194,6 +196,14 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
 		},
 	}
 
+	if helmReleaseArgs.kubeConfigSecretRef != "" {
+		helmRelease.Spec.KubeConfig = &helmv2.KubeConfig{
+			SecretRef: meta.SecretKeyReference{
+				Name: helmReleaseArgs.kubeConfigSecretRef,
+			},
+		}
+	}
+
 	if helmReleaseArgs.chartInterval != 0 {
 		helmRelease.Spec.Chart.Spec.Interval = &metav1.Duration{
 			Duration: helmReleaseArgs.chartInterval,
diff --git a/cmd/flux/create_kustomization.go b/cmd/flux/create_kustomization.go
index ef55c23c..f808a99f 100644
--- a/cmd/flux/create_kustomization.go
+++ b/cmd/flux/create_kustomization.go
@@ -42,22 +42,21 @@ var createKsCmd = &cobra.Command{
 	Use:     "kustomization [name]",
 	Aliases: []string{"ks"},
 	Short:   "Create or update a Kustomization resource",
-	Long:    "The kustomization source create command generates a Kustomize resource for a given source.",
+	Long:    "The create command generates a Kustomization resource for a given source.",
 	Example: `  # Create a Kustomization resource from a source at a given path
-  flux create kustomization contour \
-    --source=GitRepository/contour \
-    --path="./examples/contour/" \
+  flux create kustomization kyverno \
+    --source=GitRepository/kyverno \
+    --path="./config/release" \
     --prune=true \
-    --interval=10m \
-    --health-check="Deployment/contour.projectcontour" \
-    --health-check="DaemonSet/envoy.projectcontour" \
+    --interval=60m \
+    --wait=true \
     --health-check-timeout=3m
 
   # Create a Kustomization resource that depends on the previous one
-  flux create kustomization webapp \
-    --depends-on=contour \
-    --source=GitRepository/webapp \
-    --path="./deploy/overlays/dev" \
+  flux create kustomization kyverno-policies \
+    --depends-on=kyverno \
+    --source=GitRepository/kyverno-policies \
+    --path="./policies/flux" \
     --prune=true \
     --interval=5m
 
@@ -65,7 +64,7 @@ var createKsCmd = &cobra.Command{
   flux create kustomization podinfo \
     --namespace=default \
     --source=GitRepository/podinfo.flux-system \
-    --path="./deploy/overlays/dev" \
+    --path="./kustomize" \
     --prune=true \
     --interval=5m
 
@@ -78,18 +77,19 @@ var createKsCmd = &cobra.Command{
 }
 
 type kustomizationFlags struct {
-	source             flags.KustomizationSource
-	path               flags.SafeRelativePath
-	prune              bool
-	dependsOn          []string
-	validation         string
-	healthCheck        []string
-	healthTimeout      time.Duration
-	saName             string
-	decryptionProvider flags.DecryptionProvider
-	decryptionSecret   string
-	targetNamespace    string
-	wait               bool
+	source              flags.KustomizationSource
+	path                flags.SafeRelativePath
+	prune               bool
+	dependsOn           []string
+	validation          string
+	healthCheck         []string
+	healthTimeout       time.Duration
+	saName              string
+	decryptionProvider  flags.DecryptionProvider
+	decryptionSecret    string
+	targetNamespace     string
+	wait                bool
+	kubeConfigSecretRef string
 }
 
 var kustomizationArgs = NewKustomizationFlags()
@@ -107,6 +107,7 @@ func init() {
 	createKsCmd.Flags().Var(&kustomizationArgs.decryptionProvider, "decryption-provider", kustomizationArgs.decryptionProvider.Description())
 	createKsCmd.Flags().StringVar(&kustomizationArgs.decryptionSecret, "decryption-secret", "", "set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption")
 	createKsCmd.Flags().StringVar(&kustomizationArgs.targetNamespace, "target-namespace", "", "overrides the namespace of all Kustomization objects reconciled by this Kustomization")
+	createKsCmd.Flags().StringVar(&kustomizationArgs.kubeConfigSecretRef, "kubeconfig-secret-ref", "", "the name of the Kubernetes Secret that contains a key with the kubeconfig file for connecting to a remote cluster")
 	createKsCmd.Flags().MarkDeprecated("validation", "this arg is no longer used, all resources are validated using server-side apply dry-run")
 
 	createCmd.AddCommand(createKsCmd)
@@ -160,6 +161,14 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
 		},
 	}
 
+	if kustomizationArgs.kubeConfigSecretRef != "" {
+		kustomization.Spec.KubeConfig = &kustomizev1.KubeConfig{
+			SecretRef: meta.SecretKeyReference{
+				Name: kustomizationArgs.kubeConfigSecretRef,
+			},
+		}
+	}
+
 	if len(kustomizationArgs.healthCheck) > 0 && !kustomizationArgs.wait {
 		healthChecks := make([]meta.NamespacedObjectKindReference, 0)
 		for _, w := range kustomizationArgs.healthCheck {
-- 
GitLab