From cd8561e76604cd18caf24f31bc607feb9d6a999f Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Sun, 10 Feb 2019 16:07:32 -0600 Subject: [PATCH] Create new resource policy, "no-upgrade-existing" to prevent overwriting an existing resource. Signed-off-by: Michael FIG --- docs/charts_tips_and_tricks.md | 29 +++++++++++++++++++++++++++++ pkg/kube/client.go | 17 ++++++++++++++--- pkg/kube/resource_policy.go | 6 ++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/docs/charts_tips_and_tricks.md b/docs/charts_tips_and_tricks.md index e2c73b14f..c20ca67fe 100644 --- a/docs/charts_tips_and_tricks.md +++ b/docs/charts_tips_and_tricks.md @@ -235,6 +235,35 @@ orphaned. Helm will no longer manage it in any way. This can lead to problems if using `helm install --replace` on a release that has already been deleted, but has kept resources. +### Using with Random Secrets + +For the case where a chart installs a randomized secret that should not be +upgraded unless specifically overridden, but should also be deleted if the +chart is removed, you can use `"helm.sh/resource-policy": no-upgrade-existing` with +a secret such as: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "helm-random-secret.fullname" . }} +{{- if not .Values.somePassword }} + annotations: + "helm.sh/resource-policy": no-upgrade-existing +{{- end }} + labels: + app: {{ template "helm-random-secret.name" . }} + chart: {{ template "helm-random-secret.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + {{- if .Values.somePassword }} + some-password: {{ .Values.somePassword | b64enc | quote }} + {{- else }} + some-password: {{ randAlphaNum 10 | b64enc | quote }} + {{- end }} +``` + ## Using "Partials" and Template Includes Sometimes you want to create some reusable parts in your chart, whether diff --git a/pkg/kube/client.go b/pkg/kube/client.go index e897aced6..0fa57bdfc 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -23,17 +23,18 @@ import ( goerrors "errors" "fmt" "io" - "k8s.io/apimachinery/pkg/api/meta" "log" "strings" "time" - "github.com/evanphx/json-patch" + "k8s.io/apimachinery/pkg/api/meta" + + jsonpatch "github.com/evanphx/json-patch" appsv1 "k8s.io/api/apps/v1" appsv1beta1 "k8s.io/api/apps/v1beta1" appsv1beta2 "k8s.io/api/apps/v1beta2" batch "k8s.io/api/batch/v1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" extv1beta1 "k8s.io/api/extensions/v1beta1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -454,6 +455,16 @@ func createPatch(target *resource.Info, current runtime.Object) ([]byte, types.P } func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, force bool, recreate bool) error { + // Avoid the update if we have a no-upgrade-existing annotation on the target. + annotations, err := metadataAccessor.Annotations(target.Object) + if err != nil { + c.Log("Unable to get annotations on %q, err: %s", target.Name, err) + } + if annotations != nil && annotations[ResourcePolicyAnno] == NoUpgradeExistingPolicy { + c.Log("Skipping upgrade of %q due to annotation [%s=%s]", target.Name, ResourcePolicyAnno, NoUpgradeExistingPolicy) + return nil + } + patch, patchType, err := createPatch(target, currentObj) if err != nil { return fmt.Errorf("failed to create patch: %s", err) diff --git a/pkg/kube/resource_policy.go b/pkg/kube/resource_policy.go index 45cebcba8..4421f126d 100644 --- a/pkg/kube/resource_policy.go +++ b/pkg/kube/resource_policy.go @@ -24,3 +24,9 @@ const ResourcePolicyAnno = "helm.sh/resource-policy" // This resource policy type allows resources to skip being deleted // during an uninstallRelease action. const KeepPolicy = "keep" + +// NoUpgradeExistingPolicy is the resource policy type for no-upgrade-existing +// +// This resource policy type allows resources to skip upgrading +// an existing resource if it already exists. +const NoUpgradeExistingPolicy = "no-upgrade-existing"