diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 955c75ab1..3830c4eef 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -333,9 +333,15 @@ func (c *Client) Update(namespace string, originalReader, targetReader io.Reader } originalInfo := original.Get(info) + + // Resource exists in the current cluster state, but not in the current helm configuration + // See: https://github.com/helm/helm/issues/1193 for more info if originalInfo == nil { - kind := info.Mapping.GroupVersionKind.Kind - return fmt.Errorf("no %s with the name %q found", kind, info.Name) + return fmt.Errorf( + "%s %q is not managed by Helm; delete the resource from the current cluster state to let Helm manage it", + info.Mapping.GroupVersionKind.Kind, + info.Name, + ) } if err := updateResource(c, info, originalInfo.Object, force, recreate); err != nil { diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 89e630bb3..5bd9449b7 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -224,6 +224,43 @@ func TestUpdate(t *testing.T) { } } +func TestUpdateNonManagedResourceError(t *testing.T) { + actual := newPodList("starfish") + current := newPodList() + target := newPodList("starfish") + + tf := cmdtesting.NewTestFactory() + defer tf.Cleanup() + + tf.UnstructuredClient = &fake.RESTClient{ + NegotiatedSerializer: unstructuredSerializer, + Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { + p, m := req.URL.Path, req.Method + t.Logf("got request %s %s", p, m) + switch { + case p == "/namespaces/default/pods/starfish" && m == "GET": + return newResponse(200, &actual.Items[0]) + default: + t.Fatalf("unexpected request: %s %s", req.Method, req.URL.Path) + return nil, nil + } + }), + } + + c := &Client{ + Factory: tf, + Log: nopLogger, + } + + if err := c.Update(v1.NamespaceDefault, objBody(¤t), objBody(&target), false, false, 0, false); err != nil { + if err.Error() != "Pod \"starfish\" is not managed by Helm; delete the resource from the current cluster state to let Helm manage it" { + t.Fatal(err) + } + } else { + t.Fatalf("error expected") + } +} + func TestBuild(t *testing.T) { tests := []struct { name string