From 9744e9f619d3c1d8ddbe3af59e7d70d81c05dc5a Mon Sep 17 00:00:00 2001 From: Dong Gang Date: Mon, 2 Mar 2020 14:23:35 +0800 Subject: [PATCH] fix(helm): respect resource policy on ungrade Don't delete a resource on upgrade if it is annotated with helm.io/resource-policy=keep. This can cause data loss for users if the annotation is ignored(e.g. for a PVC) Close #7677 Signed-off-by: Dong Gang --- pkg/kube/client.go | 16 ++++++++++++++++ pkg/kube/resource_policy.go | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 pkg/kube/resource_policy.go diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 31dabcc5d..04f247c93 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "io" + "k8s.io/apimachinery/pkg/api/meta" "strings" "sync" "time" @@ -50,6 +51,8 @@ import ( // ErrNoObjectsVisited indicates that during a visit operation, no matching objects were found. var ErrNoObjectsVisited = errors.New("no objects visited") +var metadataAccessor = meta.NewAccessor() + // Client represents a client capable of communicating with the Kubernetes API. type Client struct { Factory Factory @@ -210,6 +213,19 @@ func (c *Client) Update(original, target ResourceList, force bool) (*Result, err for _, info := range original.Difference(target) { c.Log("Deleting %q in %s...", info.Name, info.Namespace) + + if err := info.Get(); err != nil { + c.Log("Unable to get obj %q, err: %s", info.Name, err) + } + annotations, err := metadataAccessor.Annotations(info.Object) + if err != nil { + c.Log("Unable to get annotations on %q, err: %s", info.Name, err) + } + if annotations != nil && annotations[ResourcePolicyAnno] == KeepPolicy { + c.Log("Skipping delete of %q due to annotation [%s=%s]", info.Name, ResourcePolicyAnno, KeepPolicy) + continue + } + res.Deleted = append(res.Deleted, info) if err := deleteResource(info); err != nil { if apierrors.IsNotFound(err) { diff --git a/pkg/kube/resource_policy.go b/pkg/kube/resource_policy.go new file mode 100644 index 000000000..5f391eb50 --- /dev/null +++ b/pkg/kube/resource_policy.go @@ -0,0 +1,26 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kube // import "helm.sh/helm/v3/pkg/kube" + +// ResourcePolicyAnno is the annotation name for a resource policy +const ResourcePolicyAnno = "helm.sh/resource-policy" + +// KeepPolicy is the resource policy type for keep +// +// This resource policy type allows resources to skip being deleted +// during an uninstallRelease action. +const KeepPolicy = "keep"