diff --git a/cmd/flux/create_helmrelease.go b/cmd/flux/create_helmrelease.go index c648f32e..d662f14a 100644 --- a/cmd/flux/create_helmrelease.go +++ b/cmd/flux/create_helmrelease.go @@ -68,6 +68,14 @@ var createHelmReleaseCmd = &cobra.Command{ --chart=podinfo \ --values=./my-values.yaml + # Create a HelmRelease with values from a Kubernetes secret + kubectl -n app create secret generic my-secret-values \ + --from-file=values.yaml=/path/to/my-secret-values.yaml + flux -n app create hr podinfo \ + --source=HelmRepository/podinfo \ + --chart=podinfo \ + --values-from=Secret/my-secret-values + # Create a HelmRelease with a custom release name flux create hr podinfo \ --release-name=podinfo-dev @@ -98,6 +106,7 @@ var ( hrChartVersion string hrTargetNamespace string hrValuesFile string + hrValuesFrom flags.HelmReleaseValuesFrom ) func init() { @@ -108,6 +117,7 @@ func init() { createHelmReleaseCmd.Flags().StringArrayVar(&hrDependsOn, "depends-on", nil, "HelmReleases that must be ready before this release can be installed, supported formats '' and '/'") 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") + createHelmReleaseCmd.Flags().Var(&hrValuesFrom, "values-from", hrValuesFrom.Description()) createCmd.AddCommand(createHelmReleaseCmd) } @@ -171,6 +181,13 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { helmRelease.Spec.Values = &apiextensionsv1.JSON{Raw: json} } + if hrValuesFrom.String() != "" { + helmRelease.Spec.ValuesFrom = []helmv2.ValuesReference{{ + Kind: hrValuesFrom.Kind, + Name: hrValuesFrom.Name, + }} + } + if export { return exportHelmRelease(helmRelease) } diff --git a/docs/cmd/flux_create_helmrelease.md b/docs/cmd/flux_create_helmrelease.md index e1481296..5042d80f 100644 --- a/docs/cmd/flux_create_helmrelease.md +++ b/docs/cmd/flux_create_helmrelease.md @@ -38,6 +38,14 @@ flux create helmrelease [name] [flags] --chart=podinfo \ --values=./my-values.yaml + # Create a HelmRelease with values from a Kubernetes secret + kubectl -n app create secret generic my-secret-values \ + --from-file=values.yaml=/path/to/my-secret-values.yaml + flux -n app create hr podinfo \ + --source=HelmRepository/podinfo \ + --chart=podinfo \ + --values-from=Secret/my-secret-values + # Create a HelmRelease with a custom release name flux create hr podinfo \ --release-name=podinfo-dev @@ -62,14 +70,15 @@ flux create helmrelease [name] [flags] ### Options ``` - --chart string Helm chart name or path - --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, supported formats '' and '/' - -h, --help help for helmrelease - --release-name string name used for the Helm release, defaults to a composition of '[-]' - --source helmChartSource source that contains the chart in the format '/',where kind can be one of: (HelmRepository, GitRepository, Bucket) - --target-namespace string namespace to install this release, defaults to the HelmRelease namespace - --values string local path to the values.yaml file + --chart string Helm chart name or path + --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, supported formats '' and '/' + -h, --help help for helmrelease + --release-name string name used for the Helm release, defaults to a composition of '[-]' + --source helmChartSource source that contains the chart in the format '/',where kind can be one of: (HelmRepository, GitRepository, Bucket) + --target-namespace string namespace to install this release, defaults to the HelmRelease namespace + --values string local path to the values.yaml file + --values-from helmReleaseValuesFrom Kubernetes object reference that contains the values.yaml data key in the format '/',where kind can be one of: (Secret, ConfigMap) ``` ### Options inherited from parent commands diff --git a/internal/flags/helm_release_values.go b/internal/flags/helm_release_values.go new file mode 100644 index 00000000..c7ae1f48 --- /dev/null +++ b/internal/flags/helm_release_values.go @@ -0,0 +1,71 @@ +/* +Copyright 2020 The Flux authors + +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 flags + +import ( + "fmt" + "strings" + + "github.com/fluxcd/flux2/internal/utils" +) + +var supportedHelmReleaseValuesFromKinds = []string{"Secret", "ConfigMap"} + +type HelmReleaseValuesFrom struct { + Kind string + Name string +} + +func (h *HelmReleaseValuesFrom) String() string { + if h.Name == "" { + return "" + } + return fmt.Sprintf("%s/%s", h.Kind, h.Name) +} + +func (h *HelmReleaseValuesFrom) Set(str string) error { + if strings.TrimSpace(str) == "" { + return fmt.Errorf("no values given, please specify %s", + h.Description()) + } + + sourceKind, sourceName := utils.ParseObjectKindName(str) + if sourceKind == "" { + return fmt.Errorf("invalid Kubernetes object reference '%s', must be in format /", str) + } + if !utils.ContainsItemString(supportedHelmReleaseValuesFromKinds, sourceKind) { + return fmt.Errorf("reference kind '%s' is not supported, can be one of: %s", + sourceKind, strings.Join(supportedHelmReleaseValuesFromKinds, ", ")) + } + + h.Name = sourceName + h.Kind = sourceKind + + return nil +} + +func (h *HelmReleaseValuesFrom) Type() string { + return "helmReleaseValuesFrom" +} + +func (h *HelmReleaseValuesFrom) Description() string { + return fmt.Sprintf( + "Kubernetes object reference that contains the values.yaml data key in the format '/',"+ + "where kind can be one of: (%s)", + strings.Join(supportedHelmReleaseValuesFromKinds, ", "), + ) +}