Skip to content

Commit

Permalink
Merge pull request #82 from manoj-nutanix/KRBN-6938
Browse files Browse the repository at this point in the history
✨Added support for helm options like wait, skip-crds, timeout, waitForJobs, etc.
  • Loading branch information
k8s-ci-robot authored Jun 13, 2023
2 parents 012110a + 8fc01d1 commit ecbd8f3
Show file tree
Hide file tree
Showing 11 changed files with 597 additions and 13 deletions.
115 changes: 115 additions & 0 deletions api/v1alpha1/helmchartproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,121 @@ type HelmChartProxySpec struct {
// fields from each selected workload Cluster and programatically create and set values.
// +optional
ValuesTemplate string `json:"valuesTemplate,omitempty"`

// Options represents CLI flags passed to Helm operations (i.e. install, upgrade, delete) and
// include options such as wait, skipCRDs, timeout, waitForJobs, etc.
// +optional
Options *HelmOptions `json:"options,omitempty"`
}

type HelmOptions struct {
// DisableHooks prevents hooks from running during the Helm install action.
// +optional
DisableHooks bool `json:"disableHooks,omitempty"`

// Wait enables the waiting for resources to be ready after a Helm install/upgrade has been performed.
// +optional
Wait bool `json:"wait,omitempty"`

// WaitForJobs enables waiting for jobs to complete after a Helm install/upgrade has been performed.
// +optional
WaitForJobs bool `json:"waitForJobs,omitempty"`

// DependencyUpdate indicates the Helm install/upgrade action to get missing dependencies.
// +optional
DependencyUpdate bool `json:"dependencyUpdate,omitempty"`

// Timeout is the time to wait for any individual Kubernetes operation (like
// resource creation, Jobs for hooks, etc.) during the performance of a Helm install action.
// Defaults to '10 min'.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`

// SkipCRDs controls whether CRDs should be installed during install/upgrade operation.
// By default, CRDs are installed if not already present.
// If set, no CRDs will be installed.
// +optional
SkipCRDs bool `json:"skipCRDs,omitempty"`

// SubNotes determines whether sub-notes should be rendered in the chart.
// +optional
SubNotes bool `json:"options,omitempty"`

// DisableOpenAPIValidation controls whether OpenAPI validation is enforced.
// +optional
DisableOpenAPIValidation bool `json:"disableOpenAPIValidation,omitempty"`

// Atomic indicates the installation/upgrade process to delete the installation or rollback on failure.
// If 'Atomic' is set, wait will be enabled automatically during helm install/upgrade operation.
// +optional
Atomic bool `json:"atomic,omitempty"`

// Install represents CLI flags passed to Helm install operation which can be used to control
// behaviour of helm Install operations via options like wait, skipCrds, timeout, waitForJobs, etc.
// +optional
Install *HelmInstallOptions `json:"install,omitempty"`

// Upgrade represents CLI flags passed to Helm upgrade operation which can be used to control
// behaviour of helm Upgrade operations via options like wait, skipCrds, timeout, waitForJobs, etc.
// +optional
Upgrade *HelmUpgradeOptions `json:"upgrade,omitempty"`

// Uninstall represents CLI flags passed to Helm uninstall operation which can be used to control
// behaviour of helm Uninstall operation via options like wait, timeout, etc.
// +optional
Uninstall *HelmUninstallOptions `json:"uninstall,omitempty"`
}

type HelmInstallOptions struct {
// CreateNamespace indicates the Helm install/upgrade action to create the
// HelmChartProxySpec.ReleaseNamespace if it does not exist yet.
// On uninstall, the namespace will not be garbage collected.
// If it is not specified by user, will be set to default 'true'.
// +optional
CreateNamespace *bool `json:"createNamespace,omitempty"`

// IncludeCRDs determines whether CRDs stored as a part of helm templates directory should be installed.
// +optional
IncludeCRDs bool `json:"includeCRDs,omitempty"`
}

type HelmUpgradeOptions struct {
// Force indicates to ignore certain warnings and perform the helm release upgrade anyway.
// This should be used with caution.
// +optional
Force bool `json:"force,omitempty"`

// ResetValues will reset the values to the chart's built-ins rather than merging with existing.
// +optional
ResetValues bool `json:"resetValues,omitempty"`

// ReuseValues will re-use the user's last supplied values.
// +optional
ReuseValues bool `json:"reuseValues,omitempty"`

// Recreate will (if true) recreate pods after a rollback.
// +optional
Recreate bool `json:"recreate,omitempty"`

// MaxHistory limits the maximum number of revisions saved per release
// +optional
MaxHistory int `json:"maxHistory,omitempty"`

// CleanupOnFail indicates the upgrade action to delete newly-created resources on a failed update operation.
// +optional
CleanupOnFail bool `json:"cleanupOnFail,omitempty"`
}

type HelmUninstallOptions struct {
// KeepHistory defines whether historical revisions of a release should be saved.
// If it's set, helm uninstall operation will not delete the history of the release.
// The helm storage backend (secret, configmap, etc) will be retained in the cluster.
// +optional
KeepHistory bool `json:"keepHistory,omitempty"`

// Description represents human readable information to be shown on release uninstall.
// +optional
Description string `json:"description,omitempty"`
}

// HelmChartProxyStatus defines the observed state of HelmChartProxy.
Expand Down
42 changes: 40 additions & 2 deletions api/v1alpha1/helmchartproxy_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ limitations under the License.
package v1alpha1

import (
"fmt"
"net/url"
"time"

metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
Expand All @@ -38,13 +44,29 @@ func (r *HelmChartProxy) SetupWebhookWithManager(mgr ctrl.Manager) error {

var _ webhook.Defaulter = &HelmChartProxy{}

const helmTimeoutSeconds = time.Second * 600

// Default implements webhook.Defaulter so a webhook will be registered for the type
func (p *HelmChartProxy) Default() {
helmchartproxylog.Info("default", "name", p.Name)

if p.Spec.ReleaseNamespace == "" {
p.Spec.ReleaseNamespace = "default"
}

// If 'Wait' is set, we need to set default 'Timeout' to make install successful.
if p.Spec.Options != nil && p.Spec.Options.Wait && p.Spec.Options.Timeout == nil {
p.Spec.Options.Timeout = &metaV1.Duration{Duration: helmTimeoutSeconds}
}

// If 'CreateNamespace' is not specified by user, set default value to 'true'
if p.Spec.Options != nil {
if p.Spec.Options.Install == nil {
p.Spec.Options.Install = &HelmInstallOptions{CreateNamespace: pointer.Bool(true)}
} else if p.Spec.Options.Install.CreateNamespace == nil {
p.Spec.Options.Install.CreateNamespace = pointer.Bool(true)
}
}
}

// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
Expand All @@ -56,15 +78,21 @@ var _ webhook.Validator = &HelmChartProxy{}
func (r *HelmChartProxy) ValidateCreate() error {
helmchartproxylog.Info("validate create", "name", r.Name)

// TODO(user): fill in your validation logic upon object creation.
if err := isUrlValid(r.Spec.RepoURL); err != nil {
return err
}

return nil
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (r *HelmChartProxy) ValidateUpdate(old runtime.Object) error {
helmchartproxylog.Info("validate update", "name", r.Name)

// TODO(user): fill in your validation logic upon object update.
if err := isUrlValid(r.Spec.RepoURL); err != nil {
return err
}

return nil
}

Expand All @@ -75,3 +103,13 @@ func (r *HelmChartProxy) ValidateDelete() error {
// TODO(user): fill in your validation logic upon object deletion.
return nil
}

// isUrlValid returns true if specifed repoURL is valid as per go doc https://pkg.go.dev/net/url#ParseRequestURI.
func isUrlValid(repoURL string) error {
_, err := url.ParseRequestURI(repoURL)
if err != nil {
return fmt.Errorf("specified repoURL: %s is not valid. Error - %s", repoURL, err)
}

return nil
}
5 changes: 5 additions & 0 deletions api/v1alpha1/helmreleaseproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ type HelmReleaseProxySpec struct {
// Go templating with the values from the referenced workload Cluster.
// +optional
Values string `json:"values,omitempty"`

// Options represents the helm setting options which can be used to control behaviour of helm operations(Install, Upgrade, Delete, etc)
// via options like wait, skipCrds, timeout, waitForJobs, etc.
// +optional
Options *HelmOptions `json:"options,omitempty"`
}

// HelmReleaseProxyStatus defines the observed state of HelmReleaseProxy.
Expand Down
102 changes: 99 additions & 3 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ecbd8f3

Please sign in to comment.