diff --git a/cmd/flux/create_helmrelease.go b/cmd/flux/create_helmrelease.go index a62c0027..5f78386d 100644 --- a/cmd/flux/create_helmrelease.go +++ b/cmd/flux/create_helmrelease.go @@ -116,6 +116,7 @@ type helmReleaseFlags struct { valuesFiles []string valuesFrom flags.HelmReleaseValuesFrom saName string + crds flags.CRDsPolicy } var helmReleaseArgs helmReleaseFlags @@ -130,6 +131,7 @@ func init() { createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.saName, "service-account", "", "the name of the service account to impersonate when reconciling this HelmRelease") createHelmReleaseCmd.Flags().StringArrayVar(&helmReleaseArgs.valuesFiles, "values", nil, "local path to values.yaml files") createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.valuesFrom, "values-from", helmReleaseArgs.valuesFrom.Description()) + createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.crds, "crds", helmReleaseArgs.crds.Description()) createCmd.AddCommand(createHelmReleaseCmd) } @@ -184,6 +186,11 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { helmRelease.Spec.ServiceAccountName = helmReleaseArgs.saName } + if helmReleaseArgs.crds != "" { + helmRelease.Spec.Install = &helmv2.Install{CRDs: helmv2.Create} + helmRelease.Spec.Upgrade = &helmv2.Upgrade{CRDs: helmv2.CRDsPolicy(helmReleaseArgs.crds.String())} + } + if len(helmReleaseArgs.valuesFiles) > 0 { valuesMap := make(map[string]interface{}) for _, v := range helmReleaseArgs.valuesFiles { diff --git a/docs/cmd/flux_create_helmrelease.md b/docs/cmd/flux_create_helmrelease.md index 38792c5c..15f7b1f3 100644 --- a/docs/cmd/flux_create_helmrelease.md +++ b/docs/cmd/flux_create_helmrelease.md @@ -81,6 +81,7 @@ flux create helmrelease [name] [flags] ``` --chart string Helm chart name or path --chart-version string Helm chart version, accepts a semver range (ignored for charts from GitRepository sources) + --crds crds upgrade CRDs policy, available options are: (Skip, Create, CreateReplace) --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 '[-]' diff --git a/docs/guides/sealed-secrets.md b/docs/guides/sealed-secrets.md index 81dd69b8..56469067 100644 --- a/docs/guides/sealed-secrets.md +++ b/docs/guides/sealed-secrets.md @@ -52,11 +52,12 @@ flux create helmrelease sealed-secrets \ --target-namespace=flux-system \ --source=HelmRepository/sealed-secrets \ --chart=sealed-secrets \ ---chart-version="1.13.x" +--chart-version=">=1.15.0-0" \ +--crds=CreateReplace ``` -With chart version `1.13.x` we configure helm-controller to automatically upgrade the release -when a new chart patch version is fetched by source-controller. +With chart version `>=1.15.0-0` we configure helm-controller to automatically upgrade the release +when a new chart 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 `flux-system` namespace. @@ -119,11 +120,11 @@ Helm repository manifest: apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: - name: stable + name: sealed-secrets namespace: flux-system spec: interval: 1h0m0s - url: https://charts.helm.sh/stable + url: https://bitnami-labs.github.io/sealed-secrets ``` Helm release manifest: @@ -140,11 +141,15 @@ spec: chart: sealed-secrets sourceRef: kind: HelmRepository - name: stable - version: "1.13.x" + name: sealed-secrets + version: ">=1.15.0-0" interval: 1h0m0s releaseName: sealed-secrets targetNamespace: flux-system + install: + crds: Create + upgrade: + crds: CreateReplace ``` !!! hint diff --git a/internal/flags/crds.go b/internal/flags/crds.go new file mode 100644 index 00000000..47e05e4f --- /dev/null +++ b/internal/flags/crds.go @@ -0,0 +1,60 @@ +/* +Copyright 2021 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" + + helmv2 "github.com/fluxcd/helm-controller/api/v2beta1" + + "github.com/fluxcd/flux2/internal/utils" +) + +var supportedCRDsPolicies = []string{ + string(helmv2.Skip), + string(helmv2.Create), + string(helmv2.CreateReplace), +} + +type CRDsPolicy string + +func (a *CRDsPolicy) String() string { + return string(*a) +} + +func (a *CRDsPolicy) Set(str string) error { + if strings.TrimSpace(str) == "" { + return fmt.Errorf("no upgrade CRDs policy given, must be one of: %s", + strings.Join(supportedCRDsPolicies, ", ")) + } + if !utils.ContainsItemString(supportedCRDsPolicies, str) { + return fmt.Errorf("unsupported upgrade CRDs policy '%s', must be one of: %s", + str, strings.Join(supportedCRDsPolicies, ", ")) + + } + *a = CRDsPolicy(str) + return nil +} + +func (a *CRDsPolicy) Type() string { + return "crds" +} + +func (a *CRDsPolicy) Description() string { + return fmt.Sprintf("upgrade CRDs policy, available options are: (%s)", strings.Join(supportedCRDsPolicies, ", ")) +} diff --git a/internal/flags/crds_test.go b/internal/flags/crds_test.go new file mode 100644 index 00000000..be53a461 --- /dev/null +++ b/internal/flags/crds_test.go @@ -0,0 +1,45 @@ +/* +Copyright 2021 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 TestCRDsPolicy_Set(t *testing.T) { + tests := []struct { + name string + str string + expect string + expectErr bool + }{ + {"supported", "CreateReplace", "CreateReplace", false}, + {"unsupported", "createreplace", "", true}, + {"empty", "", "", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var a CRDsPolicy + if err := a.Set(tt.str); (err != nil) != tt.expectErr { + t.Errorf("Set() error = %v, expectErr %v", err, tt.expectErr) + } + if str := a.String(); str != tt.expect { + t.Errorf("Set() = %v, expect %v", str, tt.expect) + } + }) + } +}