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