...

Source file src/github.com/fluxcd/helm-controller/api/v2/helmrelease_types.go

Documentation: github.com/fluxcd/helm-controller/api/v2

     1  /*
     2  Copyright 2024 The Flux authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v2
    18  
    19  import (
    20  	"strings"
    21  	"time"
    22  
    23  	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/types"
    26  	"sigs.k8s.io/yaml"
    27  
    28  	"github.com/fluxcd/pkg/apis/kustomize"
    29  	"github.com/fluxcd/pkg/apis/meta"
    30  )
    31  
    32  const (
    33  	// HelmReleaseKind is the kind in string format.
    34  	HelmReleaseKind = "HelmRelease"
    35  	// HelmReleaseFinalizer is set on a HelmRelease when it is first handled by
    36  	// the controller, and removed when this object is deleted.
    37  	HelmReleaseFinalizer = "finalizers.fluxcd.io"
    38  )
    39  
    40  const (
    41  	// defaultMaxHistory is the default number of Helm release versions to keep.
    42  	defaultMaxHistory = 5
    43  )
    44  
    45  // Kustomize Helm PostRenderer specification.
    46  type Kustomize struct {
    47  	// Strategic merge and JSON patches, defined as inline YAML objects,
    48  	// capable of targeting objects based on kind, label and annotation selectors.
    49  	// +optional
    50  	Patches []kustomize.Patch `json:"patches,omitempty"`
    51  
    52  	// Images is a list of (image name, new name, new tag or digest)
    53  	// for changing image names, tags or digests. This can also be achieved with a
    54  	// patch, but this operator is simpler to specify.
    55  	// +optional
    56  	Images []kustomize.Image `json:"images,omitempty" json:"images,omitempty"`
    57  }
    58  
    59  // PostRenderer contains a Helm PostRenderer specification.
    60  type PostRenderer struct {
    61  	// Kustomization to apply as PostRenderer.
    62  	// +optional
    63  	Kustomize *Kustomize `json:"kustomize,omitempty"`
    64  }
    65  
    66  // HelmReleaseSpec defines the desired state of a Helm release.
    67  // +kubebuilder:validation:XValidation:rule="(has(self.chart) && !has(self.chartRef)) || (!has(self.chart) && has(self.chartRef))", message="either chart or chartRef must be set"
    68  type HelmReleaseSpec struct {
    69  	// Chart defines the template of the v1.HelmChart that should be created
    70  	// for this HelmRelease.
    71  	// +optional
    72  	Chart *HelmChartTemplate `json:"chart,omitempty"`
    73  
    74  	// ChartRef holds a reference to a source controller resource containing the
    75  	// Helm chart artifact.
    76  	// +optional
    77  	ChartRef *CrossNamespaceSourceReference `json:"chartRef,omitempty"`
    78  
    79  	// Interval at which to reconcile the Helm release.
    80  	// +kubebuilder:validation:Type=string
    81  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
    82  	// +required
    83  	Interval metav1.Duration `json:"interval"`
    84  
    85  	// KubeConfig for reconciling the HelmRelease on a remote cluster.
    86  	// When used in combination with HelmReleaseSpec.ServiceAccountName,
    87  	// forces the controller to act on behalf of that Service Account at the
    88  	// target cluster.
    89  	// If the --default-service-account flag is set, its value will be used as
    90  	// a controller level fallback for when HelmReleaseSpec.ServiceAccountName
    91  	// is empty.
    92  	// +optional
    93  	KubeConfig *meta.KubeConfigReference `json:"kubeConfig,omitempty"`
    94  
    95  	// Suspend tells the controller to suspend reconciliation for this HelmRelease,
    96  	// it does not apply to already started reconciliations. Defaults to false.
    97  	// +optional
    98  	Suspend bool `json:"suspend,omitempty"`
    99  
   100  	// ReleaseName used for the Helm release. Defaults to a composition of
   101  	// '[TargetNamespace-]Name'.
   102  	// +kubebuilder:validation:MinLength=1
   103  	// +kubebuilder:validation:MaxLength=53
   104  	// +kubebuilder:validation:Optional
   105  	// +optional
   106  	ReleaseName string `json:"releaseName,omitempty"`
   107  
   108  	// TargetNamespace to target when performing operations for the HelmRelease.
   109  	// Defaults to the namespace of the HelmRelease.
   110  	// +kubebuilder:validation:MinLength=1
   111  	// +kubebuilder:validation:MaxLength=63
   112  	// +kubebuilder:validation:Optional
   113  	// +optional
   114  	TargetNamespace string `json:"targetNamespace,omitempty"`
   115  
   116  	// StorageNamespace used for the Helm storage.
   117  	// Defaults to the namespace of the HelmRelease.
   118  	// +kubebuilder:validation:MinLength=1
   119  	// +kubebuilder:validation:MaxLength=63
   120  	// +kubebuilder:validation:Optional
   121  	// +optional
   122  	StorageNamespace string `json:"storageNamespace,omitempty"`
   123  
   124  	// DependsOn may contain a meta.NamespacedObjectReference slice with
   125  	// references to HelmRelease resources that must be ready before this HelmRelease
   126  	// can be reconciled.
   127  	// +optional
   128  	DependsOn []meta.NamespacedObjectReference `json:"dependsOn,omitempty"`
   129  
   130  	// Timeout is the time to wait for any individual Kubernetes operation (like Jobs
   131  	// for hooks) during the performance of a Helm action. Defaults to '5m0s'.
   132  	// +kubebuilder:validation:Type=string
   133  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
   134  	// +optional
   135  	Timeout *metav1.Duration `json:"timeout,omitempty"`
   136  
   137  	// MaxHistory is the number of revisions saved by Helm for this HelmRelease.
   138  	// Use '0' for an unlimited number of revisions; defaults to '5'.
   139  	// +optional
   140  	MaxHistory *int `json:"maxHistory,omitempty"`
   141  
   142  	// The name of the Kubernetes service account to impersonate
   143  	// when reconciling this HelmRelease.
   144  	// +kubebuilder:validation:MinLength=1
   145  	// +kubebuilder:validation:MaxLength=253
   146  	// +optional
   147  	ServiceAccountName string `json:"serviceAccountName,omitempty"`
   148  
   149  	// PersistentClient tells the controller to use a persistent Kubernetes
   150  	// client for this release. When enabled, the client will be reused for the
   151  	// duration of the reconciliation, instead of being created and destroyed
   152  	// for each (step of a) Helm action.
   153  	//
   154  	// This can improve performance, but may cause issues with some Helm charts
   155  	// that for example do create Custom Resource Definitions during installation
   156  	// outside Helm's CRD lifecycle hooks, which are then not observed to be
   157  	// available by e.g. post-install hooks.
   158  	//
   159  	// If not set, it defaults to true.
   160  	//
   161  	// +optional
   162  	PersistentClient *bool `json:"persistentClient,omitempty"`
   163  
   164  	// DriftDetection holds the configuration for detecting and handling
   165  	// differences between the manifest in the Helm storage and the resources
   166  	// currently existing in the cluster.
   167  	// +optional
   168  	DriftDetection *DriftDetection `json:"driftDetection,omitempty"`
   169  
   170  	// Install holds the configuration for Helm install actions for this HelmRelease.
   171  	// +optional
   172  	Install *Install `json:"install,omitempty"`
   173  
   174  	// Upgrade holds the configuration for Helm upgrade actions for this HelmRelease.
   175  	// +optional
   176  	Upgrade *Upgrade `json:"upgrade,omitempty"`
   177  
   178  	// Test holds the configuration for Helm test actions for this HelmRelease.
   179  	// +optional
   180  	Test *Test `json:"test,omitempty"`
   181  
   182  	// Rollback holds the configuration for Helm rollback actions for this HelmRelease.
   183  	// +optional
   184  	Rollback *Rollback `json:"rollback,omitempty"`
   185  
   186  	// Uninstall holds the configuration for Helm uninstall actions for this HelmRelease.
   187  	// +optional
   188  	Uninstall *Uninstall `json:"uninstall,omitempty"`
   189  
   190  	// ValuesFrom holds references to resources containing Helm values for this HelmRelease,
   191  	// and information about how they should be merged.
   192  	ValuesFrom []ValuesReference `json:"valuesFrom,omitempty"`
   193  
   194  	// Values holds the values for this Helm release.
   195  	// +optional
   196  	Values *apiextensionsv1.JSON `json:"values,omitempty"`
   197  
   198  	// PostRenderers holds an array of Helm PostRenderers, which will be applied in order
   199  	// of their definition.
   200  	// +optional
   201  	PostRenderers []PostRenderer `json:"postRenderers,omitempty"`
   202  }
   203  
   204  // DriftDetectionMode represents the modes in which a controller can detect and
   205  // handle differences between the manifest in the Helm storage and the resources
   206  // currently existing in the cluster.
   207  type DriftDetectionMode string
   208  
   209  var (
   210  	// DriftDetectionEnabled instructs the controller to actively detect any
   211  	// changes between the manifest in the Helm storage and the resources
   212  	// currently existing in the cluster.
   213  	// If any differences are detected, the controller will automatically
   214  	// correct the cluster state by performing a Helm upgrade.
   215  	DriftDetectionEnabled DriftDetectionMode = "enabled"
   216  
   217  	// DriftDetectionWarn instructs the controller to actively detect any
   218  	// changes between the manifest in the Helm storage and the resources
   219  	// currently existing in the cluster.
   220  	// If any differences are detected, the controller will emit a warning
   221  	// without automatically correcting the cluster state.
   222  	DriftDetectionWarn DriftDetectionMode = "warn"
   223  
   224  	// DriftDetectionDisabled instructs the controller to skip detection of
   225  	// differences entirely.
   226  	// This is the default behavior, and the controller will not actively
   227  	// detect or respond to differences between the manifest in the Helm
   228  	// storage and the resources currently existing in the cluster.
   229  	DriftDetectionDisabled DriftDetectionMode = "disabled"
   230  )
   231  
   232  var (
   233  	// DriftDetectionMetadataKey is the label or annotation key used to disable
   234  	// the diffing of an object.
   235  	DriftDetectionMetadataKey = GroupVersion.Group + "/driftDetection"
   236  	// DriftDetectionDisabledValue is the value used to disable the diffing of
   237  	// an object using DriftDetectionMetadataKey.
   238  	DriftDetectionDisabledValue = "disabled"
   239  )
   240  
   241  // IgnoreRule defines a rule to selectively disregard specific changes during
   242  // the drift detection process.
   243  type IgnoreRule struct {
   244  	// Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from
   245  	// consideration in a Kubernetes object.
   246  	// +required
   247  	Paths []string `json:"paths"`
   248  
   249  	// Target is a selector for specifying Kubernetes objects to which this
   250  	// rule applies.
   251  	// If Target is not set, the Paths will be ignored for all Kubernetes
   252  	// objects within the manifest of the Helm release.
   253  	// +optional
   254  	Target *kustomize.Selector `json:"target,omitempty"`
   255  }
   256  
   257  // DriftDetection defines the strategy for performing differential analysis and
   258  // provides a way to define rules for ignoring specific changes during this
   259  // process.
   260  type DriftDetection struct {
   261  	// Mode defines how differences should be handled between the Helm manifest
   262  	// and the manifest currently applied to the cluster.
   263  	// If not explicitly set, it defaults to DiffModeDisabled.
   264  	// +kubebuilder:validation:Enum=enabled;warn;disabled
   265  	// +optional
   266  	Mode DriftDetectionMode `json:"mode,omitempty"`
   267  
   268  	// Ignore contains a list of rules for specifying which changes to ignore
   269  	// during diffing.
   270  	// +optional
   271  	Ignore []IgnoreRule `json:"ignore,omitempty"`
   272  }
   273  
   274  // GetMode returns the DiffMode set on the Diff, or DiffModeDisabled if not
   275  // set.
   276  func (d DriftDetection) GetMode() DriftDetectionMode {
   277  	if d.Mode == "" {
   278  		return DriftDetectionDisabled
   279  	}
   280  	return d.Mode
   281  }
   282  
   283  // MustDetectChanges returns true if the DiffMode is set to DiffModeEnabled or
   284  // DiffModeWarn.
   285  func (d DriftDetection) MustDetectChanges() bool {
   286  	return d.GetMode() == DriftDetectionEnabled || d.GetMode() == DriftDetectionWarn
   287  }
   288  
   289  // HelmChartTemplate defines the template from which the controller will
   290  // generate a v1.HelmChart object in the same namespace as the referenced
   291  // v1.Source.
   292  type HelmChartTemplate struct {
   293  	// ObjectMeta holds the template for metadata like labels and annotations.
   294  	// +optional
   295  	ObjectMeta *HelmChartTemplateObjectMeta `json:"metadata,omitempty"`
   296  
   297  	// Spec holds the template for the v1.HelmChartSpec for this HelmRelease.
   298  	// +required
   299  	Spec HelmChartTemplateSpec `json:"spec"`
   300  }
   301  
   302  // HelmChartTemplateObjectMeta defines the template for the ObjectMeta of a
   303  // v1.HelmChart.
   304  type HelmChartTemplateObjectMeta struct {
   305  	// Map of string keys and values that can be used to organize and categorize
   306  	// (scope and select) objects.
   307  	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
   308  	// +optional
   309  	Labels map[string]string `json:"labels,omitempty"`
   310  
   311  	// Annotations is an unstructured key value map stored with a resource that may be
   312  	// set by external tools to store and retrieve arbitrary metadata. They are not
   313  	// queryable and should be preserved when modifying objects.
   314  	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
   315  	// +optional
   316  	Annotations map[string]string `json:"annotations,omitempty"`
   317  }
   318  
   319  // HelmChartTemplateSpec defines the template from which the controller will
   320  // generate a v1.HelmChartSpec object.
   321  type HelmChartTemplateSpec struct {
   322  	// The name or path the Helm chart is available at in the SourceRef.
   323  	// +kubebuilder:validation:MinLength=1
   324  	// +kubebuilder:validation:MaxLength=2048
   325  	// +required
   326  	Chart string `json:"chart"`
   327  
   328  	// Version semver expression, ignored for charts from v1.GitRepository and
   329  	// v1beta2.Bucket sources. Defaults to latest when omitted.
   330  	// +kubebuilder:default:=*
   331  	// +optional
   332  	Version string `json:"version,omitempty"`
   333  
   334  	// The name and namespace of the v1.Source the chart is available at.
   335  	// +required
   336  	SourceRef CrossNamespaceObjectReference `json:"sourceRef"`
   337  
   338  	// Interval at which to check the v1.Source for updates. Defaults to
   339  	// 'HelmReleaseSpec.Interval'.
   340  	// +kubebuilder:validation:Type=string
   341  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
   342  	// +optional
   343  	Interval *metav1.Duration `json:"interval,omitempty"`
   344  
   345  	// Determines what enables the creation of a new artifact. Valid values are
   346  	// ('ChartVersion', 'Revision').
   347  	// See the documentation of the values for an explanation on their behavior.
   348  	// Defaults to ChartVersion when omitted.
   349  	// +kubebuilder:validation:Enum=ChartVersion;Revision
   350  	// +kubebuilder:default:=ChartVersion
   351  	// +optional
   352  	ReconcileStrategy string `json:"reconcileStrategy,omitempty"`
   353  
   354  	// Alternative list of values files to use as the chart values (values.yaml
   355  	// is not included by default), expected to be a relative path in the SourceRef.
   356  	// Values files are merged in the order of this list with the last file overriding
   357  	// the first. Ignored when omitted.
   358  	// +optional
   359  	ValuesFiles []string `json:"valuesFiles,omitempty"`
   360  
   361  	// IgnoreMissingValuesFiles controls whether to silently ignore missing values files rather than failing.
   362  	// +optional
   363  	IgnoreMissingValuesFiles bool `json:"ignoreMissingValuesFiles,omitempty"`
   364  
   365  	// Verify contains the secret name containing the trusted public keys
   366  	// used to verify the signature and specifies which provider to use to check
   367  	// whether OCI image is authentic.
   368  	// This field is only supported for OCI sources.
   369  	// Chart dependencies, which are not bundled in the umbrella chart artifact,
   370  	// are not verified.
   371  	// +optional
   372  	Verify *HelmChartTemplateVerification `json:"verify,omitempty"`
   373  }
   374  
   375  // GetInterval returns the configured interval for the v1.HelmChart,
   376  // or the given default.
   377  func (in HelmChartTemplate) GetInterval(defaultInterval metav1.Duration) metav1.Duration {
   378  	if in.Spec.Interval == nil {
   379  		return defaultInterval
   380  	}
   381  	return *in.Spec.Interval
   382  }
   383  
   384  // GetNamespace returns the namespace targeted namespace for the
   385  // v1.HelmChart, or the given default.
   386  func (in HelmChartTemplate) GetNamespace(defaultNamespace string) string {
   387  	if in.Spec.SourceRef.Namespace == "" {
   388  		return defaultNamespace
   389  	}
   390  	return in.Spec.SourceRef.Namespace
   391  }
   392  
   393  // HelmChartTemplateVerification verifies the authenticity of an OCI Helm chart.
   394  type HelmChartTemplateVerification struct {
   395  	// Provider specifies the technology used to sign the OCI Helm chart.
   396  	// +kubebuilder:validation:Enum=cosign;notation
   397  	// +kubebuilder:default:=cosign
   398  	Provider string `json:"provider"`
   399  
   400  	// SecretRef specifies the Kubernetes Secret containing the
   401  	// trusted public keys.
   402  	// +optional
   403  	SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
   404  }
   405  
   406  // Remediation defines a consistent interface for InstallRemediation and
   407  // UpgradeRemediation.
   408  // +kubebuilder:object:generate=false
   409  type Remediation interface {
   410  	GetRetries() int
   411  	MustIgnoreTestFailures(bool) bool
   412  	MustRemediateLastFailure() bool
   413  	GetStrategy() RemediationStrategy
   414  	GetFailureCount(hr *HelmRelease) int64
   415  	IncrementFailureCount(hr *HelmRelease)
   416  	RetriesExhausted(hr *HelmRelease) bool
   417  }
   418  
   419  // Install holds the configuration for Helm install actions performed for this
   420  // HelmRelease.
   421  type Install struct {
   422  	// Timeout is the time to wait for any individual Kubernetes operation (like
   423  	// Jobs for hooks) during the performance of a Helm install action. Defaults to
   424  	// 'HelmReleaseSpec.Timeout'.
   425  	// +kubebuilder:validation:Type=string
   426  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
   427  	// +optional
   428  	Timeout *metav1.Duration `json:"timeout,omitempty"`
   429  
   430  	// Remediation holds the remediation configuration for when the Helm install
   431  	// action for the HelmRelease fails. The default is to not perform any action.
   432  	// +optional
   433  	Remediation *InstallRemediation `json:"remediation,omitempty"`
   434  
   435  	// DisableWait disables the waiting for resources to be ready after a Helm
   436  	// install has been performed.
   437  	// +optional
   438  	DisableWait bool `json:"disableWait,omitempty"`
   439  
   440  	// DisableWaitForJobs disables waiting for jobs to complete after a Helm
   441  	// install has been performed.
   442  	// +optional
   443  	DisableWaitForJobs bool `json:"disableWaitForJobs,omitempty"`
   444  
   445  	// DisableHooks prevents hooks from running during the Helm install action.
   446  	// +optional
   447  	DisableHooks bool `json:"disableHooks,omitempty"`
   448  
   449  	// DisableOpenAPIValidation prevents the Helm install action from validating
   450  	// rendered templates against the Kubernetes OpenAPI Schema.
   451  	// +optional
   452  	DisableOpenAPIValidation bool `json:"disableOpenAPIValidation,omitempty"`
   453  
   454  	// DisableSchemaValidation prevents the Helm install action from validating
   455  	// the values against the JSON Schema.
   456  	// +optional
   457  	DisableSchemaValidation bool `json:"disableSchemaValidation,omitempty"`
   458  
   459  	// Replace tells the Helm install action to re-use the 'ReleaseName', but only
   460  	// if that name is a deleted release which remains in the history.
   461  	// +optional
   462  	Replace bool `json:"replace,omitempty"`
   463  
   464  	// SkipCRDs tells the Helm install action to not install any CRDs. By default,
   465  	// CRDs are installed if not already present.
   466  	//
   467  	// Deprecated use CRD policy (`crds`) attribute with value `Skip` instead.
   468  	//
   469  	// +deprecated
   470  	// +optional
   471  	SkipCRDs bool `json:"skipCRDs,omitempty"`
   472  
   473  	// CRDs upgrade CRDs from the Helm Chart's crds directory according
   474  	// to the CRD upgrade policy provided here. Valid values are `Skip`,
   475  	// `Create` or `CreateReplace`. Default is `Create` and if omitted
   476  	// CRDs are installed but not updated.
   477  	//
   478  	// Skip: do neither install nor replace (update) any CRDs.
   479  	//
   480  	// Create: new CRDs are created, existing CRDs are neither updated nor deleted.
   481  	//
   482  	// CreateReplace: new CRDs are created, existing CRDs are updated (replaced)
   483  	// but not deleted.
   484  	//
   485  	// By default, CRDs are applied (installed) during Helm install action.
   486  	// With this option users can opt in to CRD replace existing CRDs on Helm
   487  	// install actions, which is not (yet) natively supported by Helm.
   488  	// https://helm.sh/docs/chart_best_practices/custom_resource_definitions.
   489  	//
   490  	// +kubebuilder:validation:Enum=Skip;Create;CreateReplace
   491  	// +optional
   492  	CRDs CRDsPolicy `json:"crds,omitempty"`
   493  
   494  	// CreateNamespace tells the Helm install action to create the
   495  	// HelmReleaseSpec.TargetNamespace if it does not exist yet.
   496  	// On uninstall, the namespace will not be garbage collected.
   497  	// +optional
   498  	CreateNamespace bool `json:"createNamespace,omitempty"`
   499  }
   500  
   501  // GetTimeout returns the configured timeout for the Helm install action,
   502  // or the given default.
   503  func (in Install) GetTimeout(defaultTimeout metav1.Duration) metav1.Duration {
   504  	if in.Timeout == nil {
   505  		return defaultTimeout
   506  	}
   507  	return *in.Timeout
   508  }
   509  
   510  // GetRemediation returns the configured Remediation for the Helm install action.
   511  func (in Install) GetRemediation() Remediation {
   512  	if in.Remediation == nil {
   513  		return InstallRemediation{}
   514  	}
   515  	return *in.Remediation
   516  }
   517  
   518  // InstallRemediation holds the configuration for Helm install remediation.
   519  type InstallRemediation struct {
   520  	// Retries is the number of retries that should be attempted on failures before
   521  	// bailing. Remediation, using an uninstall, is performed between each attempt.
   522  	// Defaults to '0', a negative integer equals to unlimited retries.
   523  	// +optional
   524  	Retries int `json:"retries,omitempty"`
   525  
   526  	// IgnoreTestFailures tells the controller to skip remediation when the Helm
   527  	// tests are run after an install action but fail. Defaults to
   528  	// 'Test.IgnoreFailures'.
   529  	// +optional
   530  	IgnoreTestFailures *bool `json:"ignoreTestFailures,omitempty"`
   531  
   532  	// RemediateLastFailure tells the controller to remediate the last failure, when
   533  	// no retries remain. Defaults to 'false'.
   534  	// +optional
   535  	RemediateLastFailure *bool `json:"remediateLastFailure,omitempty"`
   536  }
   537  
   538  // GetRetries returns the number of retries that should be attempted on
   539  // failures.
   540  func (in InstallRemediation) GetRetries() int {
   541  	return in.Retries
   542  }
   543  
   544  // MustIgnoreTestFailures returns the configured IgnoreTestFailures or the given
   545  // default.
   546  func (in InstallRemediation) MustIgnoreTestFailures(def bool) bool {
   547  	if in.IgnoreTestFailures == nil {
   548  		return def
   549  	}
   550  	return *in.IgnoreTestFailures
   551  }
   552  
   553  // MustRemediateLastFailure returns whether to remediate the last failure when
   554  // no retries remain.
   555  func (in InstallRemediation) MustRemediateLastFailure() bool {
   556  	if in.RemediateLastFailure == nil {
   557  		return false
   558  	}
   559  	return *in.RemediateLastFailure
   560  }
   561  
   562  // GetStrategy returns the strategy to use for failure remediation.
   563  func (in InstallRemediation) GetStrategy() RemediationStrategy {
   564  	return UninstallRemediationStrategy
   565  }
   566  
   567  // GetFailureCount gets the failure count.
   568  func (in InstallRemediation) GetFailureCount(hr *HelmRelease) int64 {
   569  	return hr.Status.InstallFailures
   570  }
   571  
   572  // IncrementFailureCount increments the failure count.
   573  func (in InstallRemediation) IncrementFailureCount(hr *HelmRelease) {
   574  	hr.Status.InstallFailures++
   575  }
   576  
   577  // RetriesExhausted returns true if there are no remaining retries.
   578  func (in InstallRemediation) RetriesExhausted(hr *HelmRelease) bool {
   579  	return in.Retries >= 0 && in.GetFailureCount(hr) > int64(in.Retries)
   580  }
   581  
   582  // CRDsPolicy defines the install/upgrade approach to use for CRDs when
   583  // installing or upgrading a HelmRelease.
   584  type CRDsPolicy string
   585  
   586  const (
   587  	// Skip CRDs do neither install nor replace (update) any CRDs.
   588  	Skip CRDsPolicy = "Skip"
   589  	// Create CRDs which do not already exist, do not replace (update) already existing
   590  	// CRDs and keep (do not delete) CRDs which no longer exist in the current release.
   591  	Create CRDsPolicy = "Create"
   592  	// Create CRDs which do not already exist, Replace (update) already existing CRDs
   593  	// and keep (do not delete) CRDs which no longer exist in the current release.
   594  	CreateReplace CRDsPolicy = "CreateReplace"
   595  )
   596  
   597  // Upgrade holds the configuration for Helm upgrade actions for this
   598  // HelmRelease.
   599  type Upgrade struct {
   600  	// Timeout is the time to wait for any individual Kubernetes operation (like
   601  	// Jobs for hooks) during the performance of a Helm upgrade action. Defaults to
   602  	// 'HelmReleaseSpec.Timeout'.
   603  	// +kubebuilder:validation:Type=string
   604  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
   605  	// +optional
   606  	Timeout *metav1.Duration `json:"timeout,omitempty"`
   607  
   608  	// Remediation holds the remediation configuration for when the Helm upgrade
   609  	// action for the HelmRelease fails. The default is to not perform any action.
   610  	// +optional
   611  	Remediation *UpgradeRemediation `json:"remediation,omitempty"`
   612  
   613  	// DisableWait disables the waiting for resources to be ready after a Helm
   614  	// upgrade has been performed.
   615  	// +optional
   616  	DisableWait bool `json:"disableWait,omitempty"`
   617  
   618  	// DisableWaitForJobs disables waiting for jobs to complete after a Helm
   619  	// upgrade has been performed.
   620  	// +optional
   621  	DisableWaitForJobs bool `json:"disableWaitForJobs,omitempty"`
   622  
   623  	// DisableHooks prevents hooks from running during the Helm upgrade action.
   624  	// +optional
   625  	DisableHooks bool `json:"disableHooks,omitempty"`
   626  
   627  	// DisableOpenAPIValidation prevents the Helm upgrade action from validating
   628  	// rendered templates against the Kubernetes OpenAPI Schema.
   629  	// +optional
   630  	DisableOpenAPIValidation bool `json:"disableOpenAPIValidation,omitempty"`
   631  
   632  	// DisableSchemaValidation prevents the Helm upgrade action from validating
   633  	// the values against the JSON Schema.
   634  	// +optional
   635  	DisableSchemaValidation bool `json:"disableSchemaValidation,omitempty"`
   636  
   637  	// Force forces resource updates through a replacement strategy.
   638  	// +optional
   639  	Force bool `json:"force,omitempty"`
   640  
   641  	// PreserveValues will make Helm reuse the last release's values and merge in
   642  	// overrides from 'Values'. Setting this flag makes the HelmRelease
   643  	// non-declarative.
   644  	// +optional
   645  	PreserveValues bool `json:"preserveValues,omitempty"`
   646  
   647  	// CleanupOnFail allows deletion of new resources created during the Helm
   648  	// upgrade action when it fails.
   649  	// +optional
   650  	CleanupOnFail bool `json:"cleanupOnFail,omitempty"`
   651  
   652  	// CRDs upgrade CRDs from the Helm Chart's crds directory according
   653  	// to the CRD upgrade policy provided here. Valid values are `Skip`,
   654  	// `Create` or `CreateReplace`. Default is `Skip` and if omitted
   655  	// CRDs are neither installed nor upgraded.
   656  	//
   657  	// Skip: do neither install nor replace (update) any CRDs.
   658  	//
   659  	// Create: new CRDs are created, existing CRDs are neither updated nor deleted.
   660  	//
   661  	// CreateReplace: new CRDs are created, existing CRDs are updated (replaced)
   662  	// but not deleted.
   663  	//
   664  	// By default, CRDs are not applied during Helm upgrade action. With this
   665  	// option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm.
   666  	// https://helm.sh/docs/chart_best_practices/custom_resource_definitions.
   667  	//
   668  	// +kubebuilder:validation:Enum=Skip;Create;CreateReplace
   669  	// +optional
   670  	CRDs CRDsPolicy `json:"crds,omitempty"`
   671  }
   672  
   673  // GetTimeout returns the configured timeout for the Helm upgrade action, or the
   674  // given default.
   675  func (in Upgrade) GetTimeout(defaultTimeout metav1.Duration) metav1.Duration {
   676  	if in.Timeout == nil {
   677  		return defaultTimeout
   678  	}
   679  	return *in.Timeout
   680  }
   681  
   682  // GetRemediation returns the configured Remediation for the Helm upgrade
   683  // action.
   684  func (in Upgrade) GetRemediation() Remediation {
   685  	if in.Remediation == nil {
   686  		return UpgradeRemediation{}
   687  	}
   688  	return *in.Remediation
   689  }
   690  
   691  // UpgradeRemediation holds the configuration for Helm upgrade remediation.
   692  type UpgradeRemediation struct {
   693  	// Retries is the number of retries that should be attempted on failures before
   694  	// bailing. Remediation, using 'Strategy', is performed between each attempt.
   695  	// Defaults to '0', a negative integer equals to unlimited retries.
   696  	// +optional
   697  	Retries int `json:"retries,omitempty"`
   698  
   699  	// IgnoreTestFailures tells the controller to skip remediation when the Helm
   700  	// tests are run after an upgrade action but fail.
   701  	// Defaults to 'Test.IgnoreFailures'.
   702  	// +optional
   703  	IgnoreTestFailures *bool `json:"ignoreTestFailures,omitempty"`
   704  
   705  	// RemediateLastFailure tells the controller to remediate the last failure, when
   706  	// no retries remain. Defaults to 'false' unless 'Retries' is greater than 0.
   707  	// +optional
   708  	RemediateLastFailure *bool `json:"remediateLastFailure,omitempty"`
   709  
   710  	// Strategy to use for failure remediation. Defaults to 'rollback'.
   711  	// +kubebuilder:validation:Enum=rollback;uninstall
   712  	// +optional
   713  	Strategy *RemediationStrategy `json:"strategy,omitempty"`
   714  }
   715  
   716  // GetRetries returns the number of retries that should be attempted on
   717  // failures.
   718  func (in UpgradeRemediation) GetRetries() int {
   719  	return in.Retries
   720  }
   721  
   722  // MustIgnoreTestFailures returns the configured IgnoreTestFailures or the given
   723  // default.
   724  func (in UpgradeRemediation) MustIgnoreTestFailures(def bool) bool {
   725  	if in.IgnoreTestFailures == nil {
   726  		return def
   727  	}
   728  	return *in.IgnoreTestFailures
   729  }
   730  
   731  // MustRemediateLastFailure returns whether to remediate the last failure when
   732  // no retries remain.
   733  func (in UpgradeRemediation) MustRemediateLastFailure() bool {
   734  	if in.RemediateLastFailure == nil {
   735  		return in.Retries > 0
   736  	}
   737  	return *in.RemediateLastFailure
   738  }
   739  
   740  // GetStrategy returns the strategy to use for failure remediation.
   741  func (in UpgradeRemediation) GetStrategy() RemediationStrategy {
   742  	if in.Strategy == nil {
   743  		return RollbackRemediationStrategy
   744  	}
   745  	return *in.Strategy
   746  }
   747  
   748  // GetFailureCount gets the failure count.
   749  func (in UpgradeRemediation) GetFailureCount(hr *HelmRelease) int64 {
   750  	return hr.Status.UpgradeFailures
   751  }
   752  
   753  // IncrementFailureCount increments the failure count.
   754  func (in UpgradeRemediation) IncrementFailureCount(hr *HelmRelease) {
   755  	hr.Status.UpgradeFailures++
   756  }
   757  
   758  // RetriesExhausted returns true if there are no remaining retries.
   759  func (in UpgradeRemediation) RetriesExhausted(hr *HelmRelease) bool {
   760  	return in.Retries >= 0 && in.GetFailureCount(hr) > int64(in.Retries)
   761  }
   762  
   763  // RemediationStrategy returns the strategy to use to remediate a failed install
   764  // or upgrade.
   765  type RemediationStrategy string
   766  
   767  const (
   768  	// RollbackRemediationStrategy represents a Helm remediation strategy of Helm
   769  	// rollback.
   770  	RollbackRemediationStrategy RemediationStrategy = "rollback"
   771  
   772  	// UninstallRemediationStrategy represents a Helm remediation strategy of Helm
   773  	// uninstall.
   774  	UninstallRemediationStrategy RemediationStrategy = "uninstall"
   775  )
   776  
   777  // Test holds the configuration for Helm test actions for this HelmRelease.
   778  type Test struct {
   779  	// Enable enables Helm test actions for this HelmRelease after an Helm install
   780  	// or upgrade action has been performed.
   781  	// +optional
   782  	Enable bool `json:"enable,omitempty"`
   783  
   784  	// Timeout is the time to wait for any individual Kubernetes operation during
   785  	// the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'.
   786  	// +kubebuilder:validation:Type=string
   787  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
   788  	// +optional
   789  	Timeout *metav1.Duration `json:"timeout,omitempty"`
   790  
   791  	// IgnoreFailures tells the controller to skip remediation when the Helm tests
   792  	// are run but fail. Can be overwritten for tests run after install or upgrade
   793  	// actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'.
   794  	// +optional
   795  	IgnoreFailures bool `json:"ignoreFailures,omitempty"`
   796  
   797  	// Filters is a list of tests to run or exclude from running.
   798  	Filters *[]Filter `json:"filters,omitempty"`
   799  }
   800  
   801  // GetTimeout returns the configured timeout for the Helm test action,
   802  // or the given default.
   803  func (in Test) GetTimeout(defaultTimeout metav1.Duration) metav1.Duration {
   804  	if in.Timeout == nil {
   805  		return defaultTimeout
   806  	}
   807  	return *in.Timeout
   808  }
   809  
   810  // Filter holds the configuration for individual Helm test filters.
   811  type Filter struct {
   812  	// Name is the name of the test.
   813  	// +kubebuilder:validation:MinLength=1
   814  	// +kubebuilder:validation:MaxLength=253
   815  	// +required
   816  	Name string `json:"name"`
   817  	// Exclude specifies whether the named test should be excluded.
   818  	// +optional
   819  	Exclude bool `json:"exclude,omitempty"`
   820  }
   821  
   822  // GetFilters returns the configured filters for the Helm test action/
   823  func (in Test) GetFilters() []Filter {
   824  	if in.Filters == nil {
   825  		var filters []Filter
   826  		return filters
   827  	}
   828  	return *in.Filters
   829  }
   830  
   831  // Rollback holds the configuration for Helm rollback actions for this
   832  // HelmRelease.
   833  type Rollback struct {
   834  	// Timeout is the time to wait for any individual Kubernetes operation (like
   835  	// Jobs for hooks) during the performance of a Helm rollback action. Defaults to
   836  	// 'HelmReleaseSpec.Timeout'.
   837  	// +kubebuilder:validation:Type=string
   838  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
   839  	// +optional
   840  	Timeout *metav1.Duration `json:"timeout,omitempty"`
   841  
   842  	// DisableWait disables the waiting for resources to be ready after a Helm
   843  	// rollback has been performed.
   844  	// +optional
   845  	DisableWait bool `json:"disableWait,omitempty"`
   846  
   847  	// DisableWaitForJobs disables waiting for jobs to complete after a Helm
   848  	// rollback has been performed.
   849  	// +optional
   850  	DisableWaitForJobs bool `json:"disableWaitForJobs,omitempty"`
   851  
   852  	// DisableHooks prevents hooks from running during the Helm rollback action.
   853  	// +optional
   854  	DisableHooks bool `json:"disableHooks,omitempty"`
   855  
   856  	// Recreate performs pod restarts for the resource if applicable.
   857  	// +optional
   858  	Recreate bool `json:"recreate,omitempty"`
   859  
   860  	// Force forces resource updates through a replacement strategy.
   861  	// +optional
   862  	Force bool `json:"force,omitempty"`
   863  
   864  	// CleanupOnFail allows deletion of new resources created during the Helm
   865  	// rollback action when it fails.
   866  	// +optional
   867  	CleanupOnFail bool `json:"cleanupOnFail,omitempty"`
   868  }
   869  
   870  // GetTimeout returns the configured timeout for the Helm rollback action, or
   871  // the given default.
   872  func (in Rollback) GetTimeout(defaultTimeout metav1.Duration) metav1.Duration {
   873  	if in.Timeout == nil {
   874  		return defaultTimeout
   875  	}
   876  	return *in.Timeout
   877  }
   878  
   879  // Uninstall holds the configuration for Helm uninstall actions for this
   880  // HelmRelease.
   881  type Uninstall struct {
   882  	// Timeout is the time to wait for any individual Kubernetes operation (like
   883  	// Jobs for hooks) during the performance of a Helm uninstall action. Defaults
   884  	// to 'HelmReleaseSpec.Timeout'.
   885  	// +kubebuilder:validation:Type=string
   886  	// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
   887  	// +optional
   888  	Timeout *metav1.Duration `json:"timeout,omitempty"`
   889  
   890  	// DisableHooks prevents hooks from running during the Helm rollback action.
   891  	// +optional
   892  	DisableHooks bool `json:"disableHooks,omitempty"`
   893  
   894  	// KeepHistory tells Helm to remove all associated resources and mark the
   895  	// release as deleted, but retain the release history.
   896  	// +optional
   897  	KeepHistory bool `json:"keepHistory,omitempty"`
   898  
   899  	// DisableWait disables waiting for all the resources to be deleted after
   900  	// a Helm uninstall is performed.
   901  	// +optional
   902  	DisableWait bool `json:"disableWait,omitempty"`
   903  
   904  	// DeletionPropagation specifies the deletion propagation policy when
   905  	// a Helm uninstall is performed.
   906  	// +kubebuilder:default=background
   907  	// +kubebuilder:validation:Enum=background;foreground;orphan
   908  	// +optional
   909  	DeletionPropagation *string `json:"deletionPropagation,omitempty"`
   910  }
   911  
   912  // GetTimeout returns the configured timeout for the Helm uninstall action, or
   913  // the given default.
   914  func (in Uninstall) GetTimeout(defaultTimeout metav1.Duration) metav1.Duration {
   915  	if in.Timeout == nil {
   916  		return defaultTimeout
   917  	}
   918  	return *in.Timeout
   919  }
   920  
   921  // GetDeletionPropagation returns the configured deletion propagation policy
   922  // for the Helm uninstall action, or 'background'.
   923  func (in Uninstall) GetDeletionPropagation() string {
   924  	if in.DeletionPropagation == nil {
   925  		return "background"
   926  	}
   927  	return *in.DeletionPropagation
   928  }
   929  
   930  // ReleaseAction is the action to perform a Helm release.
   931  type ReleaseAction string
   932  
   933  const (
   934  	// ReleaseActionInstall represents a Helm install action.
   935  	ReleaseActionInstall ReleaseAction = "install"
   936  	// ReleaseActionUpgrade represents a Helm upgrade action.
   937  	ReleaseActionUpgrade ReleaseAction = "upgrade"
   938  )
   939  
   940  // HelmReleaseStatus defines the observed state of a HelmRelease.
   941  type HelmReleaseStatus struct {
   942  	// ObservedGeneration is the last observed generation.
   943  	// +optional
   944  	ObservedGeneration int64 `json:"observedGeneration,omitempty"`
   945  
   946  	// ObservedPostRenderersDigest is the digest for the post-renderers of
   947  	// the last successful reconciliation attempt.
   948  	// +optional
   949  	ObservedPostRenderersDigest string `json:"observedPostRenderersDigest,omitempty"`
   950  
   951  	// LastAttemptedGeneration is the last generation the controller attempted
   952  	// to reconcile.
   953  	// +optional
   954  	LastAttemptedGeneration int64 `json:"lastAttemptedGeneration,omitempty"`
   955  
   956  	// Conditions holds the conditions for the HelmRelease.
   957  	// +optional
   958  	Conditions []metav1.Condition `json:"conditions,omitempty"`
   959  
   960  	// HelmChart is the namespaced name of the HelmChart resource created by
   961  	// the controller for the HelmRelease.
   962  	// +optional
   963  	HelmChart string `json:"helmChart,omitempty"`
   964  
   965  	// StorageNamespace is the namespace of the Helm release storage for the
   966  	// current release.
   967  	// +kubebuilder:validation:MaxLength=63
   968  	// +kubebuilder:validation:MinLength=1
   969  	// +kubebuilder:validation:Optional
   970  	// +optional
   971  	StorageNamespace string `json:"storageNamespace,omitempty"`
   972  
   973  	// History holds the history of Helm releases performed for this HelmRelease
   974  	// up to the last successfully completed release.
   975  	// +optional
   976  	History Snapshots `json:"history,omitempty"`
   977  
   978  	// LastAttemptedReleaseAction is the last release action performed for this
   979  	// HelmRelease. It is used to determine the active remediation strategy.
   980  	// +kubebuilder:validation:Enum=install;upgrade
   981  	// +optional
   982  	LastAttemptedReleaseAction ReleaseAction `json:"lastAttemptedReleaseAction,omitempty"`
   983  
   984  	// Failures is the reconciliation failure count against the latest desired
   985  	// state. It is reset after a successful reconciliation.
   986  	// +optional
   987  	Failures int64 `json:"failures,omitempty"`
   988  
   989  	// InstallFailures is the install failure count against the latest desired
   990  	// state. It is reset after a successful reconciliation.
   991  	// +optional
   992  	InstallFailures int64 `json:"installFailures,omitempty"`
   993  
   994  	// UpgradeFailures is the upgrade failure count against the latest desired
   995  	// state. It is reset after a successful reconciliation.
   996  	// +optional
   997  	UpgradeFailures int64 `json:"upgradeFailures,omitempty"`
   998  
   999  	// LastAttemptedRevision is the Source revision of the last reconciliation
  1000  	// attempt. For OCIRepository  sources, the 12 first characters of the digest are
  1001  	// appended to the chart version e.g. "1.2.3+1234567890ab".
  1002  	// +optional
  1003  	LastAttemptedRevision string `json:"lastAttemptedRevision,omitempty"`
  1004  
  1005  	// LastAttemptedRevisionDigest is the digest of the last reconciliation attempt.
  1006  	// This is only set for OCIRepository sources.
  1007  	// +optional
  1008  	LastAttemptedRevisionDigest string `json:"lastAttemptedRevisionDigest,omitempty"`
  1009  
  1010  	// LastAttemptedValuesChecksum is the SHA1 checksum for the values of the last
  1011  	// reconciliation attempt.
  1012  	// Deprecated: Use LastAttemptedConfigDigest instead.
  1013  	// +optional
  1014  	LastAttemptedValuesChecksum string `json:"lastAttemptedValuesChecksum,omitempty"`
  1015  
  1016  	// LastReleaseRevision is the revision of the last successful Helm release.
  1017  	// Deprecated: Use History instead.
  1018  	// +optional
  1019  	LastReleaseRevision int `json:"lastReleaseRevision,omitempty"`
  1020  
  1021  	// LastAttemptedConfigDigest is the digest for the config (better known as
  1022  	// "values") of the last reconciliation attempt.
  1023  	// +optional
  1024  	LastAttemptedConfigDigest string `json:"lastAttemptedConfigDigest,omitempty"`
  1025  
  1026  	// LastHandledForceAt holds the value of the most recent force request
  1027  	// value, so a change of the annotation value can be detected.
  1028  	// +optional
  1029  	LastHandledForceAt string `json:"lastHandledForceAt,omitempty"`
  1030  
  1031  	// LastHandledResetAt holds the value of the most recent reset request
  1032  	// value, so a change of the annotation value can be detected.
  1033  	// +optional
  1034  	LastHandledResetAt string `json:"lastHandledResetAt,omitempty"`
  1035  
  1036  	meta.ReconcileRequestStatus `json:",inline"`
  1037  }
  1038  
  1039  // ClearHistory clears the History.
  1040  func (in *HelmReleaseStatus) ClearHistory() {
  1041  	in.History = nil
  1042  }
  1043  
  1044  // ClearFailures clears the failure counters.
  1045  func (in *HelmReleaseStatus) ClearFailures() {
  1046  	in.Failures = 0
  1047  	in.InstallFailures = 0
  1048  	in.UpgradeFailures = 0
  1049  }
  1050  
  1051  // GetHelmChart returns the namespace and name of the HelmChart.
  1052  func (in HelmReleaseStatus) GetHelmChart() (string, string) {
  1053  	if in.HelmChart == "" {
  1054  		return "", ""
  1055  	}
  1056  	if split := strings.Split(in.HelmChart, string(types.Separator)); len(split) > 1 {
  1057  		return split[0], split[1]
  1058  	}
  1059  	return "", ""
  1060  }
  1061  
  1062  func (in *HelmReleaseStatus) GetLastAttemptedRevision() string {
  1063  	return in.LastAttemptedRevision
  1064  }
  1065  
  1066  const (
  1067  	// SourceIndexKey is the key used for indexing HelmReleases based on
  1068  	// their sources.
  1069  	SourceIndexKey string = ".metadata.source"
  1070  )
  1071  
  1072  // +genclient
  1073  // +kubebuilder:object:root=true
  1074  // +kubebuilder:resource:shortName=hr
  1075  // +kubebuilder:storageversion
  1076  // +kubebuilder:subresource:status
  1077  // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
  1078  // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
  1079  // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
  1080  
  1081  // HelmRelease is the Schema for the helmreleases API
  1082  type HelmRelease struct {
  1083  	metav1.TypeMeta   `json:",inline"`
  1084  	metav1.ObjectMeta `json:"metadata,omitempty"`
  1085  
  1086  	Spec HelmReleaseSpec `json:"spec,omitempty"`
  1087  	// +kubebuilder:default:={"observedGeneration":-1}
  1088  	Status HelmReleaseStatus `json:"status,omitempty"`
  1089  }
  1090  
  1091  // GetDriftDetection returns the configuration for detecting and handling
  1092  // differences between the manifest in the Helm storage and the resources
  1093  // currently existing in the cluster.
  1094  func (in *HelmRelease) GetDriftDetection() DriftDetection {
  1095  	if in.Spec.DriftDetection == nil {
  1096  		return DriftDetection{}
  1097  	}
  1098  	return *in.Spec.DriftDetection
  1099  }
  1100  
  1101  // GetInstall returns the configuration for Helm install actions for the
  1102  // HelmRelease.
  1103  func (in *HelmRelease) GetInstall() Install {
  1104  	if in.Spec.Install == nil {
  1105  		return Install{}
  1106  	}
  1107  	return *in.Spec.Install
  1108  }
  1109  
  1110  // GetUpgrade returns the configuration for Helm upgrade actions for this
  1111  // HelmRelease.
  1112  func (in *HelmRelease) GetUpgrade() Upgrade {
  1113  	if in.Spec.Upgrade == nil {
  1114  		return Upgrade{}
  1115  	}
  1116  	return *in.Spec.Upgrade
  1117  }
  1118  
  1119  // GetTest returns the configuration for Helm test actions for this HelmRelease.
  1120  func (in *HelmRelease) GetTest() Test {
  1121  	if in.Spec.Test == nil {
  1122  		return Test{}
  1123  	}
  1124  	return *in.Spec.Test
  1125  }
  1126  
  1127  // GetRollback returns the configuration for Helm rollback actions for this
  1128  // HelmRelease.
  1129  func (in *HelmRelease) GetRollback() Rollback {
  1130  	if in.Spec.Rollback == nil {
  1131  		return Rollback{}
  1132  	}
  1133  	return *in.Spec.Rollback
  1134  }
  1135  
  1136  // GetUninstall returns the configuration for Helm uninstall actions for this
  1137  // HelmRelease.
  1138  func (in *HelmRelease) GetUninstall() Uninstall {
  1139  	if in.Spec.Uninstall == nil {
  1140  		return Uninstall{}
  1141  	}
  1142  	return *in.Spec.Uninstall
  1143  }
  1144  
  1145  // GetActiveRemediation returns the active Remediation configuration for the
  1146  // HelmRelease.
  1147  func (in HelmRelease) GetActiveRemediation() Remediation {
  1148  	switch in.Status.LastAttemptedReleaseAction {
  1149  	case ReleaseActionInstall:
  1150  		return in.GetInstall().GetRemediation()
  1151  	case ReleaseActionUpgrade:
  1152  		return in.GetUpgrade().GetRemediation()
  1153  	default:
  1154  		return nil
  1155  	}
  1156  }
  1157  
  1158  // GetRequeueAfter returns the duration after which the HelmRelease
  1159  // must be reconciled again.
  1160  func (in HelmRelease) GetRequeueAfter() time.Duration {
  1161  	return in.Spec.Interval.Duration
  1162  }
  1163  
  1164  // GetValues unmarshals the raw values to a map[string]interface{} and returns
  1165  // the result.
  1166  func (in HelmRelease) GetValues() map[string]interface{} {
  1167  	var values map[string]interface{}
  1168  	if in.Spec.Values != nil {
  1169  		_ = yaml.Unmarshal(in.Spec.Values.Raw, &values)
  1170  	}
  1171  	return values
  1172  }
  1173  
  1174  // GetReleaseName returns the configured release name, or a composition of
  1175  // '[TargetNamespace-]Name'.
  1176  func (in HelmRelease) GetReleaseName() string {
  1177  	if in.Spec.ReleaseName != "" {
  1178  		return in.Spec.ReleaseName
  1179  	}
  1180  	if in.Spec.TargetNamespace != "" {
  1181  		return strings.Join([]string{in.Spec.TargetNamespace, in.Name}, "-")
  1182  	}
  1183  	return in.Name
  1184  }
  1185  
  1186  // GetReleaseNamespace returns the configured TargetNamespace, or the namespace
  1187  // of the HelmRelease.
  1188  func (in HelmRelease) GetReleaseNamespace() string {
  1189  	if in.Spec.TargetNamespace != "" {
  1190  		return in.Spec.TargetNamespace
  1191  	}
  1192  	return in.Namespace
  1193  }
  1194  
  1195  // GetStorageNamespace returns the configured StorageNamespace for helm, or the namespace
  1196  // of the HelmRelease.
  1197  func (in HelmRelease) GetStorageNamespace() string {
  1198  	if in.Spec.StorageNamespace != "" {
  1199  		return in.Spec.StorageNamespace
  1200  	}
  1201  	return in.Namespace
  1202  }
  1203  
  1204  // GetHelmChartName returns the name used by the controller for the HelmChart creation.
  1205  func (in HelmRelease) GetHelmChartName() string {
  1206  	return strings.Join([]string{in.Namespace, in.Name}, "-")
  1207  }
  1208  
  1209  // GetTimeout returns the configured Timeout, or the default of 300s.
  1210  func (in HelmRelease) GetTimeout() metav1.Duration {
  1211  	if in.Spec.Timeout == nil {
  1212  		return metav1.Duration{Duration: 300 * time.Second}
  1213  	}
  1214  	return *in.Spec.Timeout
  1215  }
  1216  
  1217  // GetMaxHistory returns the configured MaxHistory, or the default of 5.
  1218  func (in HelmRelease) GetMaxHistory() int {
  1219  	if in.Spec.MaxHistory == nil {
  1220  		return defaultMaxHistory
  1221  	}
  1222  	return *in.Spec.MaxHistory
  1223  }
  1224  
  1225  // UsePersistentClient returns the configured PersistentClient, or the default
  1226  // of true.
  1227  func (in HelmRelease) UsePersistentClient() bool {
  1228  	if in.Spec.PersistentClient == nil {
  1229  		return true
  1230  	}
  1231  	return *in.Spec.PersistentClient
  1232  }
  1233  
  1234  // GetDependsOn returns the list of dependencies across-namespaces.
  1235  func (in HelmRelease) GetDependsOn() []meta.NamespacedObjectReference {
  1236  	return in.Spec.DependsOn
  1237  }
  1238  
  1239  // GetConditions returns the status conditions of the object.
  1240  func (in HelmRelease) GetConditions() []metav1.Condition {
  1241  	return in.Status.Conditions
  1242  }
  1243  
  1244  // SetConditions sets the status conditions on the object.
  1245  func (in *HelmRelease) SetConditions(conditions []metav1.Condition) {
  1246  	in.Status.Conditions = conditions
  1247  }
  1248  
  1249  // HasChartRef returns true if the HelmRelease has a ChartRef.
  1250  func (in *HelmRelease) HasChartRef() bool {
  1251  	return in.Spec.ChartRef != nil
  1252  }
  1253  
  1254  // HasChartTemplate returns true if the HelmRelease has a ChartTemplate.
  1255  func (in *HelmRelease) HasChartTemplate() bool {
  1256  	return in.Spec.Chart != nil
  1257  }
  1258  
  1259  // +kubebuilder:object:root=true
  1260  
  1261  // HelmReleaseList contains a list of HelmRelease objects.
  1262  type HelmReleaseList struct {
  1263  	metav1.TypeMeta `json:",inline"`
  1264  	metav1.ListMeta `json:"metadata,omitempty"`
  1265  	Items           []HelmRelease `json:"items"`
  1266  }
  1267  
  1268  func init() {
  1269  	SchemeBuilder.Register(&HelmRelease{}, &HelmReleaseList{})
  1270  }
  1271  

View as plain text