diff --git a/cmd/flux/create_helmrelease.go b/cmd/flux/create_helmrelease.go index b4fdcdf1..24b5f8c0 100644 --- a/cmd/flux/create_helmrelease.go +++ b/cmd/flux/create_helmrelease.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "os" + "strings" "time" "github.com/fluxcd/flux2/internal/flags" @@ -117,7 +118,7 @@ type helmReleaseFlags struct { targetNamespace string createNamespace bool valuesFiles []string - valuesFrom flags.HelmReleaseValuesFrom + valuesFrom []string saName string crds flags.CRDsPolicy reconcileStrategy string @@ -127,6 +128,8 @@ type helmReleaseFlags struct { var helmReleaseArgs helmReleaseFlags +var supportedHelmReleaseValuesFromKinds = []string{"Secret", "ConfigMap"} + func init() { createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.name, "release-name", "", "name used for the Helm release, defaults to a composition of '[-]'") createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.source, "source", helmReleaseArgs.source.Description()) @@ -139,7 +142,7 @@ func init() { createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.reconcileStrategy, "reconcile-strategy", "ChartVersion", "the reconcile strategy for helm chart created by the helm release(accepted values: Revision and ChartRevision)") createHelmReleaseCmd.Flags().DurationVarP(&helmReleaseArgs.chartInterval, "chart-interval", "", 0, "the interval of which to check for new chart versions") 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().StringSliceVar(&helmReleaseArgs.valuesFrom, "values-from", nil, "a Kubernetes object reference that contains the values.yaml data key in the format '/', where kind must be one of: (Secret,ConfigMap)") 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) @@ -260,11 +263,25 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { helmRelease.Spec.Values = &apiextensionsv1.JSON{Raw: jsonRaw} } - if helmReleaseArgs.valuesFrom.String() != "" { - helmRelease.Spec.ValuesFrom = []helmv2.ValuesReference{{ - Kind: helmReleaseArgs.valuesFrom.Kind, - Name: helmReleaseArgs.valuesFrom.Name, - }} + if len(helmReleaseArgs.valuesFrom) != 0 { + values := []helmv2.ValuesReference{} + for _, value := range helmReleaseArgs.valuesFrom { + sourceKind, sourceName := utils.ParseObjectKindName(value) + if sourceKind == "" { + return fmt.Errorf("invalid Kubernetes object reference '%s', must be in format /", value) + } + cleanSourceKind, ok := utils.ContainsEqualFoldItemString(supportedHelmReleaseValuesFromKinds, sourceKind) + if !ok { + return fmt.Errorf("reference kind '%s' is not supported, must be one of: %s", + sourceKind, strings.Join(supportedHelmReleaseValuesFromKinds, ", ")) + } + + values = append(values, helmv2.ValuesReference{ + Name: sourceName, + Kind: cleanSourceKind, + }) + } + helmRelease.Spec.ValuesFrom = values } if createArgs.export { diff --git a/internal/flags/helm_release_values.go b/internal/flags/helm_release_values.go deleted file mode 100644 index 62035be8..00000000 --- a/internal/flags/helm_release_values.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -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 (v *HelmReleaseValuesFrom) String() string { - if v.Name == "" { - return "" - } - return fmt.Sprintf("%s/%s", v.Kind, v.Name) -} - -func (v *HelmReleaseValuesFrom) Set(str string) error { - if strings.TrimSpace(str) == "" { - return fmt.Errorf("no values given, please specify %s", - v.Description()) - } - - sourceKind, sourceName := utils.ParseObjectKindName(str) - if sourceKind == "" { - return fmt.Errorf("invalid Kubernetes object reference '%s', must be in format /", str) - } - cleanSourceKind, ok := utils.ContainsEqualFoldItemString(supportedHelmReleaseValuesFromKinds, sourceKind) - if !ok { - return fmt.Errorf("reference kind '%s' is not supported, must be one of: %s", - sourceKind, strings.Join(supportedHelmReleaseValuesFromKinds, ", ")) - } - - v.Name = sourceName - v.Kind = cleanSourceKind - - return nil -} - -func (v *HelmReleaseValuesFrom) Type() string { - return "helmReleaseValuesFrom" -} - -func (v *HelmReleaseValuesFrom) Description() string { - return fmt.Sprintf( - "Kubernetes object reference that contains the values.yaml data key in the format '/', "+ - "where kind must be one of: (%s)", - strings.Join(supportedHelmReleaseValuesFromKinds, ", "), - ) -} diff --git a/internal/flags/helm_release_values_test.go b/internal/flags/helm_release_values_test.go deleted file mode 100644 index 369f64bb..00000000 --- a/internal/flags/helm_release_values_test.go +++ /dev/null @@ -1,50 +0,0 @@ -//go:build !e2e -// +build !e2e - -/* -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 ( - "testing" -) - -func TestHelmReleaseValuesFrom_Set(t *testing.T) { - tests := []struct { - name string - str string - expect string - expectErr bool - }{ - {"supported", "Secret/foo", "Secret/foo", false}, - {"lower case kind", "secret/foo", "Secret/foo", false}, - {"unsupported", "Unsupported/kind", "", true}, - {"invalid format", "Secret", "", true}, - {"empty", "", "", true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var h HelmReleaseValuesFrom - if err := h.Set(tt.str); (err != nil) != tt.expectErr { - t.Errorf("Set() error = %v, expectErr %v", err, tt.expectErr) - } - if str := h.String(); str != tt.expect { - t.Errorf("Set() = %v, expect %v", str, tt.expect) - } - }) - } -}