From b4ed1de6b8e113ab7e0bebd48d1dd809677e280a Mon Sep 17 00:00:00 2001
From: Adam Reese <adam@reese.io>
Date: Wed, 17 Oct 2018 12:53:10 -0700
Subject: [PATCH] ref(*): kubernetes v1.12 support

Signed-off-by: Adam Reese <adam@reese.io>
---
 Gopkg.lock                                 | 103 +++++++++++---------
 Gopkg.toml                                 |  20 +++-
 cmd/helm/helm.go                           |   2 +-
 pkg/kube/client.go                         | 106 ++++++++++-----------
 pkg/kube/client_test.go                    |  40 ++++----
 pkg/kube/config.go                         |   4 +-
 pkg/kube/converter.go                      |  15 ++-
 pkg/kube/factory.go                        |  38 ++++++++
 pkg/kube/log.go                            |   2 +-
 pkg/kube/result.go                         |   2 +-
 pkg/kube/result_test.go                    |   2 +-
 pkg/kube/wait.go                           |  34 +++++--
 pkg/releasetesting/environment.go          |   4 +-
 pkg/releasetesting/test_suite.go           |  10 +-
 pkg/releasetesting/test_suite_test.go      |   8 +-
 pkg/tiller/environment/environment.go      |  10 +-
 pkg/tiller/environment/environment_test.go |  10 +-
 pkg/tiller/release_server_test.go          |   8 +-
 18 files changed, 245 insertions(+), 173 deletions(-)
 create mode 100644 pkg/kube/factory.go

diff --git a/Gopkg.lock b/Gopkg.lock
index c330cf6c8..cd5e78f7f 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -393,11 +393,12 @@
   revision = "3959339b333561bf62a38b424fd41517c2c90f40"
 
 [[projects]]
-  digest = "1:06ec9147400aabb0d6960dd8557638603b5f320cd4cb8a3eceaae407e782849a"
+  digest = "1:8eb1de8112c9924d59bf1d3e5c26f5eaa2bfc2a5fcbb92dc1c2e4546d695f277"
   name = "github.com/imdario/mergo"
   packages = ["."]
   pruneopts = "UT"
-  revision = "6633656539c1639d9d78127b7d47c622b5d7b6dc"
+  revision = "9f23e2d6bd2a77f959b2bf6acdbefd708a83a4a4"
+  version = "v0.3.6"
 
 [[projects]]
   digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
@@ -689,7 +690,7 @@
   version = "v0.9.0"
 
 [[projects]]
-  digest = "1:c45031ba03b85fc3b219c46b540996b793d1c5244ae4d7046314b8d09526c2a5"
+  digest = "1:517fc596d15da8456fefaa85bcff18dd2068ade58f1e108997c2456ff0e83d3d"
   name = "gopkg.in/square/go-jose.v2"
   packages = [
     ".",
@@ -698,8 +699,7 @@
     "jwt",
   ]
   pruneopts = "UT"
-  revision = "f8f38de21b4dcd69d0413faf231983f5fd6634b1"
-  version = "v2.1.3"
+  revision = "89060dee6a84df9a4dae49f676f0c755037834f1"
 
 [[projects]]
   digest = "1:c27797c5f42d349e2a604510822df7d037415aae58bf1e6fd35624eda757c0aa"
@@ -709,8 +709,8 @@
   revision = "53feefa2559fb8dfa8d81baad31be332c97d6c77"
 
 [[projects]]
-  branch = "release-1.11"
-  digest = "1:fcc8693dcd553f6a9dfe94487fa66443a166405e4c4cce87d50bbad58c0812ce"
+  branch = "release-1.12"
+  digest = "1:16e3493f1ebd6e2c9bf2f05a2c0f0f23bd8bd346dfa27bfc5ccd29d2b77f900c"
   name = "k8s.io/api"
   packages = [
     "admission/v1beta1",
@@ -725,10 +725,12 @@
     "authorization/v1beta1",
     "autoscaling/v1",
     "autoscaling/v2beta1",
+    "autoscaling/v2beta2",
     "batch/v1",
     "batch/v1beta1",
     "batch/v2alpha1",
     "certificates/v1beta1",
+    "coordination/v1beta1",
     "core/v1",
     "events/v1beta1",
     "extensions/v1beta1",
@@ -746,7 +748,7 @@
     "storage/v1beta1",
   ]
   pruneopts = "UT"
-  revision = "61b11ee6533278ae17d77fd36825d0b47ec3a293"
+  revision = "475331a8afff5587f47d0470a93f79c60c573c03"
 
 [[projects]]
   digest = "1:b46a162d7c7e9117ae2dd9a73ee4dc2181ad9ea9d505fd7c5eb63c96211dc9dd"
@@ -756,8 +758,8 @@
   revision = "898b0eda132e1aeac43a459785144ee4bf9b0a2e"
 
 [[projects]]
-  branch = "release-1.11"
-  digest = "1:5fb786469c205f315aea2e894c4bb4532570d5d7f63e1024abd274034c19547e"
+  branch = "release-1.12"
+  digest = "1:51d5c9bf991053e2c265cf2203c843dbddfa78fed4d8b22b9072b50561accd2b"
   name = "k8s.io/apimachinery"
   packages = [
     "pkg/api/equality",
@@ -766,6 +768,7 @@
     "pkg/api/meta/testrestmapper",
     "pkg/api/resource",
     "pkg/api/validation",
+    "pkg/api/validation/path",
     "pkg/apis/meta/internalversion",
     "pkg/apis/meta/v1",
     "pkg/apis/meta/v1/unstructured",
@@ -797,6 +800,7 @@
     "pkg/util/intstr",
     "pkg/util/json",
     "pkg/util/mergepatch",
+    "pkg/util/naming",
     "pkg/util/net",
     "pkg/util/rand",
     "pkg/util/remotecommand",
@@ -814,11 +818,11 @@
     "third_party/forked/golang/reflect",
   ]
   pruneopts = "UT"
-  revision = "488889b0007f63ffee90b66a34a2deca9ec58774"
+  revision = "6dd46049f39503a1fc8d65de4bd566829e95faff"
 
 [[projects]]
-  branch = "release-1.10"
-  digest = "1:dde6031988d993fc4f0a4d13eded2b665d6c1dbfbea27e700a078a388d4a2593"
+  branch = "release-1.12"
+  digest = "1:e38fd46b96594c848ae465219e948e3ca1d3b595fc136d63b5022e625d8436bb"
   name = "k8s.io/apiserver"
   packages = [
     "pkg/apis/audit",
@@ -830,10 +834,22 @@
     "pkg/util/feature",
   ]
   pruneopts = "UT"
-  revision = "ea53f8588c655568158b4ff53f5ec6fa4ebfc332"
+  revision = "a4ed22a224c0a5f970851abac59d313a6ac803c5"
 
 [[projects]]
-  digest = "1:5acb90c7f7c2070b74fb6d693f0ce15909039ecf65d8a663591caaddf5842ecd"
+  branch = "master"
+  digest = "1:9fefce8370f58ca7701e82309446bd72ca765a1c5da83207857cebbc1bd9aeb2"
+  name = "k8s.io/cli-runtime"
+  packages = [
+    "pkg/genericclioptions",
+    "pkg/genericclioptions/printers",
+    "pkg/genericclioptions/resource",
+  ]
+  pruneopts = "UT"
+  revision = "7915b4409361b23932e7af013a2ec31d5753e001"
+
+[[projects]]
+  digest = "1:fb69e389e81d571d59b7a22ac06354e4cfec2a1d693362117b330977cad8d69a"
   name = "k8s.io/client-go"
   packages = [
     "discovery",
@@ -865,6 +881,8 @@
     "kubernetes/typed/autoscaling/v1/fake",
     "kubernetes/typed/autoscaling/v2beta1",
     "kubernetes/typed/autoscaling/v2beta1/fake",
+    "kubernetes/typed/autoscaling/v2beta2",
+    "kubernetes/typed/autoscaling/v2beta2/fake",
     "kubernetes/typed/batch/v1",
     "kubernetes/typed/batch/v1/fake",
     "kubernetes/typed/batch/v1beta1",
@@ -873,6 +891,8 @@
     "kubernetes/typed/batch/v2alpha1/fake",
     "kubernetes/typed/certificates/v1beta1",
     "kubernetes/typed/certificates/v1beta1/fake",
+    "kubernetes/typed/coordination/v1beta1",
+    "kubernetes/typed/coordination/v1beta1/fake",
     "kubernetes/typed/core/v1",
     "kubernetes/typed/core/v1/fake",
     "kubernetes/typed/events/v1beta1",
@@ -901,8 +921,6 @@
     "kubernetes/typed/storage/v1alpha1/fake",
     "kubernetes/typed/storage/v1beta1",
     "kubernetes/typed/storage/v1beta1/fake",
-    "listers/apps/v1",
-    "listers/core/v1",
     "pkg/apis/clientauthentication",
     "pkg/apis/clientauthentication/v1alpha1",
     "pkg/apis/clientauthentication/v1beta1",
@@ -938,6 +956,7 @@
     "tools/record",
     "tools/reference",
     "tools/remotecommand",
+    "tools/watch",
     "transport",
     "transport/spdy",
     "util/buffer",
@@ -951,8 +970,8 @@
     "util/retry",
   ]
   pruneopts = "UT"
-  revision = "1f13a808da65775f22cbf47862c4e5898d8f4ca1"
-  version = "kubernetes-1.11.2"
+  revision = "cb4883f3dea0a8d72fc4af710798a980992a773d"
+  version = "kubernetes-1.12.1"
 
 [[projects]]
   digest = "1:8a5fb6a585e27c0339096c0db745795940a7e72a7925e7c4cf40b76bd113d382"
@@ -966,8 +985,8 @@
   revision = "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf"
 
 [[projects]]
-  branch = "release-1.11"
-  digest = "1:0b8f7f69212ed74043de94c089008d6c3d58c53e4d08a13abec73419339d4180"
+  branch = "release-1.12"
+  digest = "1:fa66cfb06184d37bcf1fa085a91ba8f5c9d3a0c440f72c7bf898c3162a848617"
   name = "k8s.io/kubernetes"
   packages = [
     "pkg/api/events",
@@ -976,11 +995,7 @@
     "pkg/api/ref",
     "pkg/api/resource",
     "pkg/api/service",
-    "pkg/api/testapi",
     "pkg/api/v1/pod",
-    "pkg/apis/admission",
-    "pkg/apis/admission/install",
-    "pkg/apis/admission/v1beta1",
     "pkg/apis/admissionregistration",
     "pkg/apis/admissionregistration/install",
     "pkg/apis/admissionregistration/v1alpha1",
@@ -1002,6 +1017,7 @@
     "pkg/apis/autoscaling/install",
     "pkg/apis/autoscaling/v1",
     "pkg/apis/autoscaling/v2beta1",
+    "pkg/apis/autoscaling/v2beta2",
     "pkg/apis/batch",
     "pkg/apis/batch/install",
     "pkg/apis/batch/v1",
@@ -1010,9 +1026,9 @@
     "pkg/apis/certificates",
     "pkg/apis/certificates/install",
     "pkg/apis/certificates/v1beta1",
-    "pkg/apis/componentconfig",
-    "pkg/apis/componentconfig/install",
-    "pkg/apis/componentconfig/v1alpha1",
+    "pkg/apis/coordination",
+    "pkg/apis/coordination/install",
+    "pkg/apis/coordination/v1beta1",
     "pkg/apis/core",
     "pkg/apis/core/helper",
     "pkg/apis/core/helper/qos",
@@ -1027,9 +1043,6 @@
     "pkg/apis/extensions",
     "pkg/apis/extensions/install",
     "pkg/apis/extensions/v1beta1",
-    "pkg/apis/imagepolicy",
-    "pkg/apis/imagepolicy/install",
-    "pkg/apis/imagepolicy/v1alpha1",
     "pkg/apis/networking",
     "pkg/apis/networking/install",
     "pkg/apis/networking/v1",
@@ -1064,6 +1077,7 @@
     "pkg/client/clientset_generated/internalclientset/typed/autoscaling/internalversion",
     "pkg/client/clientset_generated/internalclientset/typed/batch/internalversion",
     "pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion",
+    "pkg/client/clientset_generated/internalclientset/typed/coordination/internalversion",
     "pkg/client/clientset_generated/internalclientset/typed/core/internalversion",
     "pkg/client/clientset_generated/internalclientset/typed/events/internalversion",
     "pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion",
@@ -1088,9 +1102,6 @@
     "pkg/kubectl/cmd/util/openapi",
     "pkg/kubectl/cmd/util/openapi/testing",
     "pkg/kubectl/cmd/util/openapi/validation",
-    "pkg/kubectl/genericclioptions",
-    "pkg/kubectl/genericclioptions/printers",
-    "pkg/kubectl/genericclioptions/resource",
     "pkg/kubectl/scheme",
     "pkg/kubectl/util",
     "pkg/kubectl/util/hash",
@@ -1118,20 +1129,23 @@
     "pkg/util/net/sets",
     "pkg/util/node",
     "pkg/util/parsers",
-    "pkg/util/pointer",
     "pkg/util/slice",
     "pkg/util/taints",
     "pkg/version",
   ]
   pruneopts = "UT"
-  revision = "6c8b476f24edb0abfb143e87238045d1d9aa73e6"
+  revision = "8ea5d6e20648a2bdf056105a75e7307c9e15c3f2"
 
 [[projects]]
-  digest = "1:5271b4ee2724d8c2ad7df650a5f9db46d01ce558769469713feba0e3e6079292"
+  branch = "master"
+  digest = "1:b587a79602928eab5971377f9fddc392cd047202ac4d6aae8845e10bd8634d78"
   name = "k8s.io/utils"
-  packages = ["exec"]
+  packages = [
+    "exec",
+    "pointer",
+  ]
   pruneopts = "UT"
-  revision = "aedf551cdb8b0119df3a19c65fde413a13b34997"
+  revision = "f024bbd3a09501e18d1973b22be7188c5c005014"
 
 [[projects]]
   digest = "1:96f9b7c99c55e6063371088376d57d398f42888dedd08ab5d35065aba11e3965"
@@ -1187,25 +1201,24 @@
     "k8s.io/apimachinery/pkg/util/wait",
     "k8s.io/apimachinery/pkg/version",
     "k8s.io/apimachinery/pkg/watch",
+    "k8s.io/cli-runtime/pkg/genericclioptions",
+    "k8s.io/cli-runtime/pkg/genericclioptions/resource",
     "k8s.io/client-go/discovery",
     "k8s.io/client-go/kubernetes",
     "k8s.io/client-go/kubernetes/fake",
+    "k8s.io/client-go/kubernetes/scheme",
     "k8s.io/client-go/kubernetes/typed/core/v1",
     "k8s.io/client-go/plugin/pkg/client/auth",
     "k8s.io/client-go/rest/fake",
+    "k8s.io/client-go/tools/clientcmd",
+    "k8s.io/client-go/tools/watch",
     "k8s.io/client-go/util/homedir",
     "k8s.io/kubernetes/pkg/api/legacyscheme",
-    "k8s.io/kubernetes/pkg/api/testapi",
-    "k8s.io/kubernetes/pkg/api/v1/pod",
     "k8s.io/kubernetes/pkg/apis/batch",
-    "k8s.io/kubernetes/pkg/apis/core",
-    "k8s.io/kubernetes/pkg/apis/core/v1/helper",
     "k8s.io/kubernetes/pkg/controller/deployment/util",
     "k8s.io/kubernetes/pkg/kubectl/cmd/get",
     "k8s.io/kubernetes/pkg/kubectl/cmd/testing",
     "k8s.io/kubernetes/pkg/kubectl/cmd/util",
-    "k8s.io/kubernetes/pkg/kubectl/genericclioptions",
-    "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource",
     "k8s.io/kubernetes/pkg/kubectl/scheme",
     "k8s.io/kubernetes/pkg/kubectl/validation",
   ]
diff --git a/Gopkg.toml b/Gopkg.toml
index effd828fa..3e558b9ba 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -33,19 +33,23 @@
 
 [[constraint]]
   name = "k8s.io/api"
-  branch = "release-1.11"
+  branch = "release-1.12"
 
 [[constraint]]
   name = "k8s.io/apimachinery"
-  branch = "release-1.11"
+  branch = "release-1.12"
 
 [[constraint]]
-  version = "kubernetes-1.11.2"
+  version = "kubernetes-1.12.1"
   name = "k8s.io/client-go"
 
 [[constraint]]
   name = "k8s.io/kubernetes"
-  branch = "release-1.11"
+  branch = "release-1.12"
+
+[[override]]
+  name = "k8s.io/apiserver"
+  branch = "release-1.12"
 
 [[override]]
   name = "github.com/json-iterator/go"
@@ -55,6 +59,14 @@
   name = "github.com/Azure/go-autorest"
   revision = "1ff28809256a84bb6966640ff3d0371af82ccba4"
 
+[[override]]
+  name = "github.com/imdario/mergo"
+  version = "v0.3.5"
+
+[[override]]
+  name = "gopkg.in/square/go-jose.v2"
+  revision = "89060dee6a84df9a4dae49f676f0c755037834f1"
+
 [prune]
   go-tests = true
   unused-packages = true
diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go
index fd3e39302..7471dbaf8 100644
--- a/cmd/helm/helm.go
+++ b/cmd/helm/helm.go
@@ -23,8 +23,8 @@ import (
 	"sync"
 
 	// Import to initialize client auth plugins.
+	"k8s.io/cli-runtime/pkg/genericclioptions"
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
 
 	"k8s.io/helm/pkg/helm"
 	"k8s.io/helm/pkg/helm/environment"
diff --git a/pkg/kube/client.go b/pkg/kube/client.go
index d8e0bda4d..3fe2aecf3 100644
--- a/pkg/kube/client.go
+++ b/pkg/kube/client.go
@@ -18,6 +18,7 @@ package kube // import "k8s.io/helm/pkg/kube"
 
 import (
 	"bytes"
+	"context"
 	"encoding/json"
 	"fmt"
 	"io"
@@ -43,28 +44,26 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/strategicpatch"
 	"k8s.io/apimachinery/pkg/watch"
+	"k8s.io/cli-runtime/pkg/genericclioptions"
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
+	"k8s.io/client-go/kubernetes"
+	watchtools "k8s.io/client-go/tools/watch"
 	"k8s.io/kubernetes/pkg/api/legacyscheme"
 	batchinternal "k8s.io/kubernetes/pkg/apis/batch"
-	"k8s.io/kubernetes/pkg/apis/core"
 	"k8s.io/kubernetes/pkg/kubectl/cmd/get"
 	cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
-	"k8s.io/kubernetes/pkg/kubectl/validation"
 )
 
-const (
-	// MissingGetHeader is added to Get's output when a resource is not found.
-	MissingGetHeader = "==> MISSING\nKIND\t\tNAME\n"
-)
+// MissingGetHeader is added to Get's output when a resource is not found.
+const MissingGetHeader = "==> MISSING\nKIND\t\tNAME\n"
 
 // ErrNoObjectsVisited indicates that during a visit operation, no matching objects were found.
 var ErrNoObjectsVisited = goerrors.New("no objects visited")
 
 // Client represents a client capable of communicating with the Kubernetes API.
 type Client struct {
-	cmdutil.Factory
-	Log func(string, ...interface{})
+	Factory Factory
+	Log     func(string, ...interface{})
 }
 
 // New creates a new Client.
@@ -78,6 +77,10 @@ func New(getter genericclioptions.RESTClientGetter) *Client {
 	}
 }
 
+func (c *Client) KubernetesClientSet() (*kubernetes.Clientset, error) {
+	return c.Factory.KubernetesClientSet()
+}
+
 var nopLogger = func(_ string, _ ...interface{}) {}
 
 // ResourceActorFunc performs an action on a single resource.
@@ -103,27 +106,24 @@ func (c *Client) Create(namespace string, reader io.Reader, timeout int64, shoul
 }
 
 func (c *Client) namespace() string {
-	if ns, _, err := c.ToRawKubeConfigLoader().Namespace(); err == nil {
+	if ns, _, err := c.Factory.ToRawKubeConfigLoader().Namespace(); err == nil {
 		return ns
 	}
 	return v1.NamespaceDefault
 }
 
-func (c *Client) newBuilder(namespace string, reader io.Reader) *resource.Result {
-	return c.NewBuilder().
+// newBuilder returns a new resource builder for structured api objects.
+func (c *Client) newBuilder() *resource.Builder {
+	return c.Factory.NewBuilder().
 		ContinueOnError().
-		WithScheme(legacyscheme.Scheme).
-		Schema(c.validator()).
 		NamespaceParam(c.namespace()).
 		DefaultNamespace().
 		RequireNamespace().
-		Stream(reader, "").
-		Flatten().
-		Do()
+		Flatten()
 }
 
-func (c *Client) validator() validation.Schema {
-	schema, err := c.Validator(true)
+func (c *Client) validator() resource.ContentValidator {
+	schema, err := c.Factory.Validator(true)
 	if err != nil {
 		c.Log("warning: failed to load schema: %s", err)
 	}
@@ -134,14 +134,9 @@ func (c *Client) validator() validation.Schema {
 func (c *Client) BuildUnstructured(namespace string, reader io.Reader) (Result, error) {
 	var result Result
 
-	result, err := c.NewBuilder().
+	result, err := c.newBuilder().
 		Unstructured().
-		ContinueOnError().
-		NamespaceParam(c.namespace()).
-		DefaultNamespace().
-		RequireNamespace().
 		Stream(reader, "").
-		Flatten().
 		Do().Infos()
 	return result, scrubValidationError(err)
 }
@@ -149,7 +144,12 @@ func (c *Client) BuildUnstructured(namespace string, reader io.Reader) (Result,
 // Build validates for Kubernetes objects and returns resource Infos from a io.Reader.
 func (c *Client) Build(namespace string, reader io.Reader) (Result, error) {
 	var result Result
-	result, err := c.newBuilder(namespace, reader).Infos()
+	result, err := c.newBuilder().
+		WithScheme(legacyscheme.Scheme).
+		Schema(c.validator()).
+		Stream(reader, "").
+		Do().
+		Infos()
 	return result, scrubValidationError(err)
 }
 
@@ -165,7 +165,7 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
 		return "", err
 	}
 
-	var objPods = make(map[string][]core.Pod)
+	var objPods = make(map[string][]v1.Pod)
 
 	missing := []string{}
 	err = perform(infos, func(info *resource.Info) error {
@@ -369,7 +369,7 @@ func perform(infos Result, fn ResourceActorFunc) error {
 }
 
 func createResource(info *resource.Info) error {
-	obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
+	obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object, nil)
 	if err != nil {
 		return err
 	}
@@ -439,7 +439,7 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
 		// send patch to server
 		helper := resource.NewHelper(target.Client, target.Mapping)
 
-		obj, err := helper.Patch(target.Namespace, target.Name, patchType, patch)
+		obj, err := helper.Patch(target.Namespace, target.Name, patchType, patch, nil)
 		if err != nil {
 			kind := target.Mapping.GroupVersionKind.Kind
 			log.Printf("Cannot patch %s: %q (%v)", kind, target.Name, err)
@@ -480,12 +480,12 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
 		return nil
 	}
 
-	client, err := c.ClientSet()
+	client, err := c.KubernetesClientSet()
 	if err != nil {
 		return err
 	}
 
-	pods, err := client.Core().Pods(target.Namespace).List(metav1.ListOptions{
+	pods, err := client.CoreV1().Pods(target.Namespace).List(metav1.ListOptions{
 		FieldSelector: fields.Everything().String(),
 		LabelSelector: labels.Set(selector).AsSelector().String(),
 	})
@@ -498,7 +498,7 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
 		c.Log("Restarting pod: %v/%v", pod.Namespace, pod.Name)
 
 		// Delete each pod for get them restarted with changed spec.
-		if err := client.Core().Pods(pod.Namespace).Delete(pod.Name, metav1.NewPreconditionDeleteOptions(string(pod.UID))); err != nil {
+		if err := client.CoreV1().Pods(pod.Namespace).Delete(pod.Name, metav1.NewPreconditionDeleteOptions(string(pod.UID))); err != nil {
 			return err
 		}
 	}
@@ -562,7 +562,9 @@ func (c *Client) watchUntilReady(timeout time.Duration, info *resource.Info) err
 	// In the future, we might want to add some special logic for types
 	// like Ingress, Volume, etc.
 
-	_, err = watch.Until(timeout, w, func(e watch.Event) (bool, error) {
+	ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout)
+	defer cancel()
+	_, err = watchtools.UntilWithoutRetry(ctx, w, func(e watch.Event) (bool, error) {
 		switch e.Type {
 		case watch.Added, watch.Modified:
 			// For things like a secret or a config map, this is the best indicator
@@ -598,9 +600,9 @@ func (c *Client) waitForJob(e watch.Event, name string) (bool, error) {
 	}
 
 	for _, c := range o.Status.Conditions {
-		if c.Type == batchinternal.JobComplete && c.Status == core.ConditionTrue {
+		if c.Type == batchinternal.JobComplete && c.Status == "True" {
 			return true, nil
-		} else if c.Type == batchinternal.JobFailed && c.Status == core.ConditionTrue {
+		} else if c.Type == batchinternal.JobFailed && c.Status == "True" {
 			return true, goerrors.Errorf("job failed: %s", c.Reason)
 		}
 	}
@@ -624,26 +626,26 @@ func scrubValidationError(err error) error {
 
 // WaitAndGetCompletedPodPhase waits up to a timeout until a pod enters a completed phase
 // and returns said phase (PodSucceeded or PodFailed qualify).
-func (c *Client) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (core.PodPhase, error) {
+func (c *Client) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error) {
 	infos, err := c.Build(namespace, reader)
 	if err != nil {
-		return core.PodUnknown, err
+		return v1.PodUnknown, err
 	}
 	info := infos[0]
 
 	kind := info.Mapping.GroupVersionKind.Kind
 	if kind != "Pod" {
-		return core.PodUnknown, goerrors.Errorf("%s is not a Pod", info.Name)
+		return v1.PodUnknown, goerrors.Errorf("%s is not a Pod", info.Name)
 	}
 
 	if err := c.watchPodUntilComplete(timeout, info); err != nil {
-		return core.PodUnknown, err
+		return v1.PodUnknown, err
 	}
 
 	if err := info.Get(); err != nil {
-		return core.PodUnknown, err
+		return v1.PodUnknown, err
 	}
-	status := info.Object.(*core.Pod).Status.Phase
+	status := info.Object.(*v1.Pod).Status.Phase
 
 	return status, nil
 }
@@ -655,15 +657,17 @@ func (c *Client) watchPodUntilComplete(timeout time.Duration, info *resource.Inf
 	}
 
 	c.Log("Watching pod %s for completion with timeout of %v", info.Name, timeout)
-	_, err = watch.Until(timeout, w, func(e watch.Event) (bool, error) {
+	ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout)
+	defer cancel()
+	_, err = watchtools.UntilWithoutRetry(ctx, w, func(e watch.Event) (bool, error) {
 		switch e.Type {
 		case watch.Deleted:
 			return false, errors.NewNotFound(schema.GroupResource{Resource: "pods"}, "")
 		}
 		switch t := e.Object.(type) {
-		case *core.Pod:
+		case *v1.Pod:
 			switch t.Status.Phase {
-			case core.PodFailed, core.PodSucceeded:
+			case v1.PodFailed, v1.PodSucceeded:
 				return true, nil
 			}
 		}
@@ -675,7 +679,7 @@ func (c *Client) watchPodUntilComplete(timeout time.Duration, info *resource.Inf
 
 //get a kubernetes resources' relation pods
 // kubernetes resource used select labels to relate pods
-func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]core.Pod) (map[string][]core.Pod, error) {
+func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]v1.Pod) (map[string][]v1.Pod, error) {
 	if info == nil {
 		return objPods, nil
 	}
@@ -695,9 +699,9 @@ func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]
 		return objPods, nil
 	}
 
-	client, _ := c.ClientSet()
+	client, _ := c.KubernetesClientSet()
 
-	pods, err := client.Core().Pods(info.Namespace).List(metav1.ListOptions{
+	pods, err := client.CoreV1().Pods(info.Namespace).List(metav1.ListOptions{
 		FieldSelector: fields.Everything().String(),
 		LabelSelector: labels.Set(selector).AsSelector().String(),
 	})
@@ -722,7 +726,7 @@ func (c *Client) getSelectRelationPod(info *resource.Info, objPods map[string][]
 	return objPods, nil
 }
 
-func isFoundPod(podItem []core.Pod, pod core.Pod) bool {
+func isFoundPod(podItem []v1.Pod, pod v1.Pod) bool {
 	for _, value := range podItem {
 		if (value.Namespace == pod.Namespace) && (value.Name == pod.Name) {
 			return true
@@ -730,7 +734,3 @@ func isFoundPod(podItem []core.Pod, pod core.Pod) bool {
 	}
 	return false
 }
-
-func asVersioned(info *resource.Info) runtime.Object {
-	return cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
-}
diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go
index acfcd0e35..84dc6fc6e 100644
--- a/pkg/kube/client_test.go
+++ b/pkg/kube/client_test.go
@@ -24,52 +24,51 @@ import (
 	"strings"
 	"testing"
 
+	"k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
 	"k8s.io/client-go/rest/fake"
-	"k8s.io/kubernetes/pkg/api/legacyscheme"
-	"k8s.io/kubernetes/pkg/api/testapi"
-	"k8s.io/kubernetes/pkg/apis/core"
 	cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
 	"k8s.io/kubernetes/pkg/kubectl/scheme"
 )
 
 var unstructuredSerializer = resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer
+var codec = scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
 
-func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
+func objBody(obj runtime.Object) io.ReadCloser {
 	return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
 }
 
-func newPod(name string) core.Pod {
-	return newPodWithStatus(name, core.PodStatus{}, "")
+func newPod(name string) v1.Pod {
+	return newPodWithStatus(name, v1.PodStatus{}, "")
 }
 
-func newPodWithStatus(name string, status core.PodStatus, namespace string) core.Pod {
-	ns := core.NamespaceDefault
+func newPodWithStatus(name string, status v1.PodStatus, namespace string) v1.Pod {
+	ns := v1.NamespaceDefault
 	if namespace != "" {
 		ns = namespace
 	}
-	return core.Pod{
+	return v1.Pod{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      name,
 			Namespace: ns,
 			SelfLink:  "/api/v1/namespaces/default/pods/" + name,
 		},
-		Spec: core.PodSpec{
-			Containers: []core.Container{{
+		Spec: v1.PodSpec{
+			Containers: []v1.Container{{
 				Name:  "app:v4",
 				Image: "abc/app:v4",
-				Ports: []core.ContainerPort{{Name: "http", ContainerPort: 80}},
+				Ports: []v1.ContainerPort{{Name: "http", ContainerPort: 80}},
 			}},
 		},
 		Status: status,
 	}
 }
 
-func newPodList(names ...string) core.PodList {
-	var list core.PodList
+func newPodList(names ...string) v1.PodList {
+	var list v1.PodList
 	for _, name := range names {
 		list.Items = append(list.Items, newPod(name))
 	}
@@ -89,7 +88,7 @@ func notFoundBody() *metav1.Status {
 func newResponse(code int, obj runtime.Object) (*http.Response, error) {
 	header := http.Header{}
 	header.Set("Content-Type", runtime.ContentTypeJSON)
-	body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Default.Codec(), obj))))
+	body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
 	return &http.Response{StatusCode: code, Header: header, Body: body}, nil
 }
 
@@ -108,12 +107,12 @@ func TestUpdate(t *testing.T) {
 	listA := newPodList("starfish", "otter", "squid")
 	listB := newPodList("starfish", "otter", "dolphin")
 	listC := newPodList("starfish", "otter", "dolphin")
-	listB.Items[0].Spec.Containers[0].Ports = []core.ContainerPort{{Name: "https", ContainerPort: 443}}
-	listC.Items[0].Spec.Containers[0].Ports = []core.ContainerPort{{Name: "https", ContainerPort: 443}}
+	listB.Items[0].Spec.Containers[0].Ports = []v1.ContainerPort{{Name: "https", ContainerPort: 443}}
+	listC.Items[0].Spec.Containers[0].Ports = []v1.ContainerPort{{Name: "https", ContainerPort: 443}}
 
 	var actions []string
 
-	tf := cmdtesting.NewTestFactory()
+	tf := cmdtesting.NewTestFactory().WithNamespace("default")
 	defer tf.Cleanup()
 	tf.UnstructuredClient = &fake.RESTClient{
 		NegotiatedSerializer: unstructuredSerializer,
@@ -154,8 +153,7 @@ func TestUpdate(t *testing.T) {
 		Factory: tf,
 		Log:     nopLogger,
 	}
-	codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
-	if err := c.Update(core.NamespaceDefault, objBody(codec, &listA), objBody(codec, &listB), false, false, 0, false); err != nil {
+	if err := c.Update(v1.NamespaceDefault, objBody(&listA), objBody(&listB), false, false, 0, false); err != nil {
 		t.Fatal(err)
 	}
 	// TODO: Find a way to test methods that use Client Set
diff --git a/pkg/kube/config.go b/pkg/kube/config.go
index 602ec8c6d..2e430d5ac 100644
--- a/pkg/kube/config.go
+++ b/pkg/kube/config.go
@@ -16,9 +16,7 @@ limitations under the License.
 
 package kube // import "k8s.io/helm/pkg/kube"
 
-import (
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
-)
+import "k8s.io/cli-runtime/pkg/genericclioptions"
 
 // GetConfig returns a Kubernetes client config.
 func GetConfig(kubeconfig, context, namespace string) *genericclioptions.ConfigFlags {
diff --git a/pkg/kube/converter.go b/pkg/kube/converter.go
index 32661f645..b056129e9 100644
--- a/pkg/kube/converter.go
+++ b/pkg/kube/converter.go
@@ -17,24 +17,21 @@ limitations under the License.
 package kube // import "k8s.io/helm/pkg/kube"
 
 import (
-	"k8s.io/apimachinery/pkg/api/meta"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
 	"k8s.io/kubernetes/pkg/api/legacyscheme"
 )
 
-// AsDefaultVersionedOrOriginal returns the object as a Go object in the external form if possible (matching the
-// group version kind of the mapping if provided, a best guess based on serialization if not provided, or obj if it cannot be converted.
-// TODO update call sites to specify the scheme they want on their builder.
-func AsDefaultVersionedOrOriginal(obj runtime.Object, mapping *meta.RESTMapping) runtime.Object {
+func asVersioned(info *resource.Info) runtime.Object {
 	converter := runtime.ObjectConvertor(legacyscheme.Scheme)
 	groupVersioner := runtime.GroupVersioner(schema.GroupVersions(legacyscheme.Scheme.PrioritizedVersionsAllGroups()))
-	if mapping != nil {
-		groupVersioner = mapping.GroupVersionKind.GroupVersion()
+	if info.Mapping != nil {
+		groupVersioner = info.Mapping.GroupVersionKind.GroupVersion()
 	}
 
-	if obj, err := converter.ConvertToVersion(obj, groupVersioner); err == nil {
+	if obj, err := converter.ConvertToVersion(info.Object, groupVersioner); err == nil {
 		return obj
 	}
-	return obj
+	return info.Object
 }
diff --git a/pkg/kube/factory.go b/pkg/kube/factory.go
new file mode 100644
index 000000000..26dad8379
--- /dev/null
+++ b/pkg/kube/factory.go
@@ -0,0 +1,38 @@
+/*
+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 "k8s.io/helm/pkg/kube"
+
+import (
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/tools/clientcmd"
+	"k8s.io/kubernetes/pkg/kubectl/validation"
+)
+
+// Factory provides abstractions that allow the Kubectl command to be extended across multiple types
+// of resources and different API sets.
+type Factory interface {
+	// ToRawKubeConfigLoader return kubeconfig loader as-is
+	ToRawKubeConfigLoader() clientcmd.ClientConfig
+	// KubernetesClientSet gives you back an external clientset
+	KubernetesClientSet() (*kubernetes.Clientset, error)
+	// NewBuilder returns an object that assists in loading objects from both disk and the server
+	// and which implements the common patterns for CLI interactions with generic resources.
+	NewBuilder() *resource.Builder
+	// Returns a schema that can validate objects stored on disk.
+	Validator(validate bool) (validation.Schema, error)
+}
diff --git a/pkg/kube/log.go b/pkg/kube/log.go
index fc3683b1d..24dafc9e0 100644
--- a/pkg/kube/log.go
+++ b/pkg/kube/log.go
@@ -24,7 +24,7 @@ import (
 
 func init() {
 	if level := os.Getenv("KUBE_LOG_LEVEL"); level != "" {
-		flag.Set("vmodule", fmt.Sprintf("loader=%s,round_trippers=%s,request=%s", level, level, level))
+		flag.Set("vmodule", fmt.Sprintf("loader=%[1]s,round_trippers=%[1]s,request=%[1]s", level))
 		flag.Set("logtostderr", "true")
 	}
 }
diff --git a/pkg/kube/result.go b/pkg/kube/result.go
index 0c6289e49..cc222a66f 100644
--- a/pkg/kube/result.go
+++ b/pkg/kube/result.go
@@ -16,7 +16,7 @@ limitations under the License.
 
 package kube // import "k8s.io/helm/pkg/kube"
 
-import "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
+import "k8s.io/cli-runtime/pkg/genericclioptions/resource"
 
 // Result provides convenience methods for comparing collections of Infos.
 type Result []*resource.Info
diff --git a/pkg/kube/result_test.go b/pkg/kube/result_test.go
index 503473c05..c4cf989b8 100644
--- a/pkg/kube/result_test.go
+++ b/pkg/kube/result_test.go
@@ -21,7 +21,7 @@ import (
 
 	"k8s.io/apimachinery/pkg/api/meta"
 	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
 )
 
 func TestResult(t *testing.T) {
diff --git a/pkg/kube/wait.go b/pkg/kube/wait.go
index 960409df9..ebd12b4b1 100644
--- a/pkg/kube/wait.go
+++ b/pkg/kube/wait.go
@@ -29,8 +29,6 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/util/wait"
 	"k8s.io/client-go/kubernetes"
-	podutil "k8s.io/kubernetes/pkg/api/v1/pod"
-	"k8s.io/kubernetes/pkg/apis/core/v1/helper"
 	deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
 )
 
@@ -50,11 +48,13 @@ func (c *Client) waitForResources(timeout time.Duration, created Result) error {
 		return err
 	}
 	return wait.Poll(2*time.Second, timeout, func() (bool, error) {
-		pods := []v1.Pod{}
-		services := []v1.Service{}
-		pvc := []v1.PersistentVolumeClaim{}
-		deployments := []deployment{}
-		for _, v := range created {
+		var (
+			pods        []v1.Pod
+			services    []v1.Service
+			pvc         []v1.PersistentVolumeClaim
+			deployments []deployment
+		)
+		for _, v := range created[:0] {
 			switch value := asVersioned(v).(type) {
 			case *v1.ReplicationController:
 				list, err := getPods(kcs, value.Namespace, value.Spec.Selector)
@@ -203,7 +203,7 @@ func (c *Client) waitForResources(timeout time.Duration, created Result) error {
 
 func (c *Client) podsReady(pods []v1.Pod) bool {
 	for _, pod := range pods {
-		if !podutil.IsPodReady(&pod) {
+		if !IsPodReady(&pod) {
 			c.Log("Pod is not ready: %s/%s", pod.GetNamespace(), pod.GetName())
 			return false
 		}
@@ -211,6 +211,16 @@ func (c *Client) podsReady(pods []v1.Pod) bool {
 	return true
 }
 
+// IsPodReady returns true if a pod is ready; false otherwise.
+func IsPodReady(pod *v1.Pod) bool {
+	for _, c := range pod.Status.Conditions {
+		if c.Type == v1.PodReady && c.Status == v1.ConditionTrue {
+			return true
+		}
+	}
+	return false
+}
+
 func (c *Client) servicesReady(svc []v1.Service) bool {
 	for _, s := range svc {
 		// ExternalName Services are external to cluster so helm shouldn't be checking to see if they're 'ready' (i.e. have an IP Set)
@@ -219,7 +229,7 @@ func (c *Client) servicesReady(svc []v1.Service) bool {
 		}
 
 		// Make sure the service is not explicitly set to "None" before checking the IP
-		if s.Spec.ClusterIP != v1.ClusterIPNone && !helper.IsServiceIPSet(&s) {
+		if s.Spec.ClusterIP != v1.ClusterIPNone && !IsServiceIPSet(&s) {
 			c.Log("Service is not ready: %s/%s", s.GetNamespace(), s.GetName())
 			return false
 		}
@@ -232,6 +242,12 @@ func (c *Client) servicesReady(svc []v1.Service) bool {
 	return true
 }
 
+// this function aims to check if the service's ClusterIP is set or not
+// the objective is not to perform validation here
+func IsServiceIPSet(service *v1.Service) bool {
+	return service.Spec.ClusterIP != v1.ClusterIPNone && service.Spec.ClusterIP != ""
+}
+
 func (c *Client) volumesReady(vols []v1.PersistentVolumeClaim) bool {
 	for _, v := range vols {
 		if v.Status.Phase != v1.ClaimBound {
diff --git a/pkg/releasetesting/environment.go b/pkg/releasetesting/environment.go
index 1899f672d..fcb52e84d 100644
--- a/pkg/releasetesting/environment.go
+++ b/pkg/releasetesting/environment.go
@@ -22,7 +22,7 @@ import (
 	"log"
 	"time"
 
-	"k8s.io/kubernetes/pkg/apis/core"
+	"k8s.io/api/core/v1"
 
 	"k8s.io/helm/pkg/hapi"
 	"k8s.io/helm/pkg/hapi/release"
@@ -48,7 +48,7 @@ func (env *Environment) createTestPod(test *test) error {
 	return nil
 }
 
-func (env *Environment) getTestPodStatus(test *test) (core.PodPhase, error) {
+func (env *Environment) getTestPodStatus(test *test) (v1.PodPhase, error) {
 	b := bytes.NewBufferString(test.manifest)
 	status, err := env.KubeClient.WaitAndGetCompletedPodPhase(env.Namespace, b, time.Duration(env.Timeout)*time.Second)
 	if err != nil {
diff --git a/pkg/releasetesting/test_suite.go b/pkg/releasetesting/test_suite.go
index 55206af4a..590f01370 100644
--- a/pkg/releasetesting/test_suite.go
+++ b/pkg/releasetesting/test_suite.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/ghodss/yaml"
 	"github.com/pkg/errors"
-	"k8s.io/kubernetes/pkg/apis/core"
+	"k8s.io/api/core/v1"
 
 	"k8s.io/helm/pkg/hapi/release"
 	"k8s.io/helm/pkg/hooks"
@@ -82,7 +82,7 @@ func (ts *TestSuite) Run(env *Environment) error {
 		}
 
 		resourceCleanExit := true
-		status := core.PodUnknown
+		status := v1.PodUnknown
 		if resourceCreated {
 			status, err = env.getTestPodStatus(test)
 			if err != nil {
@@ -111,15 +111,15 @@ func (ts *TestSuite) Run(env *Environment) error {
 	return nil
 }
 
-func (t *test) assignTestResult(podStatus core.PodPhase) error {
+func (t *test) assignTestResult(podStatus v1.PodPhase) error {
 	switch podStatus {
-	case core.PodSucceeded:
+	case v1.PodSucceeded:
 		if t.expectedSuccess {
 			t.result.Status = release.TestRunSuccess
 		} else {
 			t.result.Status = release.TestRunFailure
 		}
-	case core.PodFailed:
+	case v1.PodFailed:
 		if !t.expectedSuccess {
 			t.result.Status = release.TestRunSuccess
 		} else {
diff --git a/pkg/releasetesting/test_suite_test.go b/pkg/releasetesting/test_suite_test.go
index 04e5cea89..4e8d152a6 100644
--- a/pkg/releasetesting/test_suite_test.go
+++ b/pkg/releasetesting/test_suite_test.go
@@ -21,7 +21,7 @@ import (
 	"testing"
 	"time"
 
-	"k8s.io/kubernetes/pkg/apis/core"
+	"k8s.io/api/core/v1"
 
 	"k8s.io/helm/pkg/hapi"
 	"k8s.io/helm/pkg/hapi/release"
@@ -250,11 +250,11 @@ type mockKubeClient struct {
 	err     error
 }
 
-func (c *mockKubeClient) WaitAndGetCompletedPodPhase(_ string, _ io.Reader, _ time.Duration) (core.PodPhase, error) {
+func (c *mockKubeClient) WaitAndGetCompletedPodPhase(_ string, _ io.Reader, _ time.Duration) (v1.PodPhase, error) {
 	if c.podFail {
-		return core.PodFailed, nil
+		return v1.PodFailed, nil
 	}
-	return core.PodSucceeded, nil
+	return v1.PodSucceeded, nil
 }
 func (c *mockKubeClient) Get(_ string, _ io.Reader) (string, error) {
 	return "", nil
diff --git a/pkg/tiller/environment/environment.go b/pkg/tiller/environment/environment.go
index 39d881a9c..8a166fe23 100644
--- a/pkg/tiller/environment/environment.go
+++ b/pkg/tiller/environment/environment.go
@@ -26,8 +26,8 @@ import (
 	"io"
 	"time"
 
-	"k8s.io/kubernetes/pkg/apis/core"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
+	"k8s.io/api/core/v1"
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
 
 	"k8s.io/helm/pkg/kube"
 )
@@ -82,7 +82,7 @@ type KubeClient interface {
 
 	// WaitAndGetCompletedPodPhase waits up to a timeout until a pod enters a completed phase
 	// and returns said phase (PodSucceeded or PodFailed qualify).
-	WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (core.PodPhase, error)
+	WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error)
 }
 
 // PrintingKubeClient implements KubeClient, but simply prints the reader to
@@ -134,7 +134,7 @@ func (p *PrintingKubeClient) BuildUnstructured(ns string, reader io.Reader) (kub
 }
 
 // WaitAndGetCompletedPodPhase implements KubeClient WaitAndGetCompletedPodPhase.
-func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (core.PodPhase, error) {
+func (p *PrintingKubeClient) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error) {
 	_, err := io.Copy(p.Out, reader)
-	return core.PodUnknown, err
+	return v1.PodUnknown, err
 }
diff --git a/pkg/tiller/environment/environment_test.go b/pkg/tiller/environment/environment_test.go
index a98ceb180..fe458479f 100644
--- a/pkg/tiller/environment/environment_test.go
+++ b/pkg/tiller/environment/environment_test.go
@@ -22,8 +22,8 @@ import (
 	"testing"
 	"time"
 
-	"k8s.io/kubernetes/pkg/apis/core"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
+	"k8s.io/api/core/v1"
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
 
 	"k8s.io/helm/pkg/kube"
 )
@@ -51,11 +51,11 @@ func (k *mockKubeClient) Build(ns string, reader io.Reader) (kube.Result, error)
 func (k *mockKubeClient) BuildUnstructured(ns string, reader io.Reader) (kube.Result, error) {
 	return []*resource.Info{}, nil
 }
-func (k *mockKubeClient) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (core.PodPhase, error) {
-	return core.PodUnknown, nil
+func (k *mockKubeClient) WaitAndGetCompletedPodPhase(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error) {
+	return v1.PodUnknown, nil
 }
 
-func (k *mockKubeClient) WaitAndGetCompletedPodStatus(namespace string, reader io.Reader, timeout time.Duration) (core.PodPhase, error) {
+func (k *mockKubeClient) WaitAndGetCompletedPodStatus(namespace string, reader io.Reader, timeout time.Duration) (v1.PodPhase, error) {
 	return "", nil
 }
 
diff --git a/pkg/tiller/release_server_test.go b/pkg/tiller/release_server_test.go
index 70a2dc31c..3115341b6 100644
--- a/pkg/tiller/release_server_test.go
+++ b/pkg/tiller/release_server_test.go
@@ -28,9 +28,9 @@ import (
 
 	"github.com/ghodss/yaml"
 	"github.com/pkg/errors"
+	"k8s.io/api/core/v1"
+	"k8s.io/cli-runtime/pkg/genericclioptions/resource"
 	"k8s.io/client-go/kubernetes/fake"
-	"k8s.io/kubernetes/pkg/apis/core"
-	"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
 
 	"k8s.io/helm/pkg/chart"
 	"k8s.io/helm/pkg/engine"
@@ -492,8 +492,8 @@ func (kc *mockHooksKubeClient) Build(_ string, _ io.Reader) (kube.Result, error)
 func (kc *mockHooksKubeClient) BuildUnstructured(_ string, _ io.Reader) (kube.Result, error) {
 	return []*resource.Info{}, nil
 }
-func (kc *mockHooksKubeClient) WaitAndGetCompletedPodPhase(_ string, _ io.Reader, _ time.Duration) (core.PodPhase, error) {
-	return core.PodUnknown, nil
+func (kc *mockHooksKubeClient) WaitAndGetCompletedPodPhase(_ string, _ io.Reader, _ time.Duration) (v1.PodPhase, error) {
+	return v1.PodUnknown, nil
 }
 
 func deletePolicyStub(kubeClient *mockHooksKubeClient) *ReleaseServer {
-- 
GitLab