Repository: kubernetes-sigs/gcp-compute-persistent-disk-csi-driver
Pull request #693 (2021-01-11 09:41:39)

Allow to label PD disk with k8s cluster ID
/kind feature

**What this PR does / why we need it**:
Inspired by the similar feature of [AWS EBS CSI driver](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/cmd/main.go#L37): allow to optionally label the PD disk with cluster ID to denote the disk ownership. This allows e.g. better automated resource cleanup on cluster teardown.

**Special notes for your reviewer**:
The label was meant to be named `kubernetes.io/cluster/<cluster ID>` (again, taken from the [EBS CSI](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/pkg/driver/constants.go#L61) driver) however GCE API does not allow '/' or '.' characters in the label, so I swapped them for underscores. I can change it to anything else, I'm more interested in comments on the general approach.

**Does this PR introduce a user-facing change?**:
```release-note
A new `k8s-tag-cluster-id` command line option has been added. If specified, the resulting PD disk will be labelled with "kubernetes_io_cluster_<cluster ID>": "owned".
```


k8s-ci-robot: Welcome @tsmetana! <br><br>It looks like this is your first PR to <a href='https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver'>kubernetes-sigs/gcp-compute-persistent-disk-csi-driver</a> 🎉. Please refer to our [pull request process documentation](https://git.k8s.io/community/contributors/guide/pull-requests.md) to help your PR have a smooth ride to approval. <br><br>You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. [Here is the bot commands documentation](https://go.k8s.io/bot-commands). <br><br>You can also check if kubernetes-sigs/gcp-compute-persistent-disk-csi-driver has [its own contribution guidelines](https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/tree/master/CONTRIBUTING.md). <br><br>You may want to refer to our [testing guide](https://git.k8s.io/community/contributors/devel/sig-testing/testing.md) if you run into trouble with your tests not passing. <br><br>If you are having difficulty getting your pull request seen, please follow the [recommended escalation practices](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#why-is-my-pull-request-not-getting-reviewed). Also, for tips and tricks in the contribution process you may want to read the [Kubernetes contributor cheat sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md). We want to make sure your contribution gets all the attention it needs! <br><br>Thank you, and welcome to Kubernetes. :smiley:
k8s-ci-robot: Hi @tsmetana. Thanks for your PR.

I'm waiting for a [kubernetes-sigs](https://github.com/orgs/kubernetes-sigs/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://git.k8s.io/community/community-membership.md#member) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fgcp-compute-persistent-disk-csi-driver).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/pull/693#" title="Author self-approved">tsmetana</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **saad-ali** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @saad-ali` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fgcp-compute-persistent-disk-csi-driver).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["saad-ali"]} -->
tsmetana: @jsafrane: FYI...
mattcary: 
Thanks Thomas. I haven't had a chance to look at this yet. Have you seen https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/pull/566? The author We were basically happy with that PR, but the author seems to have dropped out. We want to get that in soon though.

If we had the ability of that CL (to label the PD disk via storage class parameters), would that fit your use case? That might be more flexible than a flag with a hardcoded label.


msau42: /ok-to-test
msau42: > If we had the ability of that CL (to label the PD disk via storage class parameters), would that fit your use case? That might be more flexible than a flag with a hardcoded label.

I think the main downside is then people can't use the default storageclass, unless we had a way to generate default storageclasses and inject the cluster name into it (k8s doesn't have a first class concept of cluster name)
mattcary: > I think the main downside is then people can't use the default storageclass, unless we had a way to generate default storageclasses and inject the cluster name into it (k8s doesn't have a first class concept of cluster name)

Since this proposal involves a command-line flag for the driver, anyone who can install the driver can also change the default storageclass to have whatever label they want.

Since this label isn't going to match the AWS EBS label anyway due to the slash-vs-underscore issue, there probably needs to be flexibility for the operator to tweak the label to what is most convenient for their tools. Doing that via the storageclass parameter seems nicer than via a driver command-line argument.

My $0.02 at least.
msau42: previous discussion: https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/issues/469
tsmetana: > > I think the main downside is then people can't use the default storageclass, unless we had a way to generate default storageclasses and inject the cluster name into it (k8s doesn't have a first class concept of cluster name)
> 
> Since this proposal involves a command-line flag for the driver, anyone who can install the driver can also change the default storageclass to have whatever label they want.

The users able to install drivers and those able to create storage classes might be different. The aim is to be able to create an environment where the clusters get automatically set-up (click in a browser) and torn-down (another click) and don't leave any leftovers while still not require any additional responsibilities from their admins (not forget to label StorageClasses).

mattcary: > The users able to install drivers and those able to create storage classes might be different. The aim is to be able to create an environment where the clusters get automatically set-up (click in a browser) and torn-down (another click) and don't leave any leftovers while still not require any additional responsibilities from their admins (not forget to label StorageClasses).

Okay, that makes sense. I think fixing the label format here will be too restrictive. I'd support a change that was something like --additional-pd-label, eg --additional-pd-label=k8s-cluster-id-112233. The flag could even be given multiple times, for multiple labels.
jsafrane: AWS has `--extra-tags=foo=bar,baz=qux`, maybe `--extra-labels`? Not sure if `pd` should be in the parameter - should it affect also snapshots?
mattcary: > AWS has `--extra-tags=foo=bar,baz=qux`, maybe `--extra-labels`? Not sure if `pd` should be in the parameter - should it affect also snapshots?

+1 to both the name as well as labeling snapshots in addition to disks.
tsmetana: Changed to allow generic disk labelling. PTAL.

Patch:
diff --git a/cmd/gce-pd-csi-driver/main.go b/cmd/gce-pd-csi-driver/main.go
index a99e405f..2da2d1ce 100644
--- a/cmd/gce-pd-csi-driver/main.go
+++ b/cmd/gce-pd-csi-driver/main.go
@@ -24,6 +24,7 @@ import (
 
 	"k8s.io/klog"
 
+	cliflag "k8s.io/component-base/cli/flag"
 	gce "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-cloud-provider/compute"
 	metadataservice "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-cloud-provider/metadata"
 	driver "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/gce-pd-csi-driver"
@@ -35,6 +36,7 @@ var (
 	endpoint             = flag.String("endpoint", "unix:/tmp/csi.sock", "CSI endpoint")
 	runControllerService = flag.Bool("run-controller-service", true, "If set to false then the CSI driver does not activate its controller service (default: true)")
 	runNodeService       = flag.Bool("run-node-service", true, "If set to false then the CSI driver does not activate its node service (default: true)")
+	extraVolumeLabels    map[string]string
 	version              string
 )
 
@@ -53,6 +55,7 @@ func init() {
 }
 
 func main() {
+	flag.Var(cliflag.NewMapStringString(&extraVolumeLabels), "extra-labels", "Extra labels to attach to each PD created. It is a comma separated list of key value pairs like '<key1>=<value1>,<key2>=<value2>'")
 	flag.Parse()
 	rand.Seed(time.Now().UnixNano())
 	handle()
@@ -104,7 +107,7 @@ func handle() {
 		nodeServer = driver.NewNodeServer(gceDriver, mounter, deviceUtils, meta, statter)
 	}
 
-	err = gceDriver.SetupGCEDriver(driverName, version, identityServer, controllerServer, nodeServer)
+	err = gceDriver.SetupGCEDriver(driverName, version, extraVolumeLabels, identityServer, controllerServer, nodeServer)
 	if err != nil {
 		klog.Fatalf("Failed to initialize GCE CSI Driver: %v", err)
 	}
diff --git a/deploy/kubernetes/base/controller/controller.yaml b/deploy/kubernetes/base/controller/controller.yaml
index ffb2f83e..44ab3064 100644
--- a/deploy/kubernetes/base/controller/controller.yaml
+++ b/deploy/kubernetes/base/controller/controller.yaml
@@ -28,7 +28,7 @@ spec:
             - "--v=5"
             - "--csi-address=/csi/csi.sock"
             - "--feature-gates=Topology=true"
-            - "--http-endpoint=:22011"
+            - "--metrics-address=:22011"
             - "--leader-election-namespace=$(PDCSI_NAMESPACE)"
             - "--timeout=250s"
             - "--extra-create-metadata"
@@ -41,18 +41,6 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-          ports:
-            - containerPort: 22011
-              name: http-endpoint
-              protocol: TCP
-          livenessProbe:
-            failureThreshold: 1
-            httpGet:
-              path: /healthz/leader-election
-              port: http-endpoint
-            initialDelaySeconds: 10
-            timeoutSeconds: 10
-            periodSeconds: 20
           volumeMounts:
             - name: socket-dir
               mountPath: /csi
@@ -61,7 +49,7 @@ spec:
           args:
             - "--v=5"
             - "--csi-address=/csi/csi.sock"
-            - "--http-endpoint=:22012"
+            - "--metrics-address=:22012"
             - "--leader-election"
             - "--leader-election-namespace=$(PDCSI_NAMESPACE)"
             - "--timeout=250s"
@@ -70,18 +58,6 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-          ports:
-            - containerPort: 22012
-              name: http-endpoint
-              protocol: TCP
-          livenessProbe:
-            failureThreshold: 1
-            httpGet:
-              path: /healthz/leader-election
-              port: http-endpoint
-            initialDelaySeconds: 10
-            timeoutSeconds: 10
-            periodSeconds: 20
           volumeMounts:
             - name: socket-dir
               mountPath: /csi
@@ -90,7 +66,7 @@ spec:
           args:
             - "--v=5"
             - "--csi-address=/csi/csi.sock"
-            - "--http-endpoint=:22013"
+            - "--metrics-address=:22013"
             - "--leader-election"
             - "--leader-election-namespace=$(PDCSI_NAMESPACE)"
             - "--handle-volume-inuse-error=false"
@@ -99,18 +75,6 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-          ports:
-            - containerPort: 22013
-              name: http-endpoint
-              protocol: TCP
-          livenessProbe:
-            failureThreshold: 1
-            httpGet:
-              path: /healthz/leader-election
-              port: http-endpoint
-            initialDelaySeconds: 10
-            timeoutSeconds: 10
-            periodSeconds: 20
           volumeMounts:
             - name: socket-dir
               mountPath: /csi
diff --git a/deploy/kubernetes/base/node_linux/node.yaml b/deploy/kubernetes/base/node_linux/node.yaml
index 51b5c8b8..e047bf24 100644
--- a/deploy/kubernetes/base/node_linux/node.yaml
+++ b/deploy/kubernetes/base/node_linux/node.yaml
@@ -45,7 +45,6 @@ spec:
           args:
             - "--v=5"
             - "--endpoint=unix:/csi/csi.sock"
-            - "--run-controller-service=false"
           securityContext:
             privileged: true
           volumeMounts:
diff --git a/deploy/kubernetes/base/node_windows/node.yaml b/deploy/kubernetes/base/node_windows/node.yaml
index b2f72f14..a14452fa 100644
--- a/deploy/kubernetes/base/node_windows/node.yaml
+++ b/deploy/kubernetes/base/node_windows/node.yaml
@@ -6,11 +6,11 @@ metadata:
 spec:
   selector:
     matchLabels:
-      app: gcp-compute-persistent-disk-csi-driver
+      app: gcp-compute-persistent-disk-csi-driver-win
   template:
     metadata:
       labels:
-        app: gcp-compute-persistent-disk-csi-driver
+        app: gcp-compute-persistent-disk-csi-driver-win
     spec:
       # Host network must be used for interaction with Workload Identity in GKE
       # since it replaces GCE Metadata Server with GKE Metadata Server. Remove
@@ -24,7 +24,7 @@ spec:
         kubernetes.io/os: windows
       containers:
         - name: csi-driver-registrar
-          image: k8s.gcr.io/sig-storage/csi-node-driver-registrar
+          image: gke.gcr.io/k8s-staging-csi/csi-node-driver-registrar-win
           args:
             - --v=5
             - --csi-address=unix://C:\\csi\\csi.sock
@@ -46,13 +46,15 @@ spec:
           args:
             - "--v=5"
             - "--endpoint=unix:/csi/csi.sock"
-            - "--run-controller-service=false"
           volumeMounts:
             - name: kubelet-dir
               mountPath: C:\var\lib\kubelet
               mountPropagation: "None"
             - name: plugin-dir
               mountPath: C:\csi
+            # TODO: check overlay and remove v1beta1 if it is safe
+            - name: csi-proxy-disk-v1beta1
+              mountPath: \\.\pipe\csi-proxy-disk-v1beta1
             - name: csi-proxy-volume-v1beta1
               mountPath: \\.\pipe\csi-proxy-volume-v1beta1
             - name: csi-proxy-filesystem-v1beta1
@@ -60,6 +62,10 @@ spec:
             - name: csi-proxy-disk-v1beta2
               mountPath: \\.\pipe\csi-proxy-disk-v1beta2
       volumes:
+      - name: csi-proxy-disk-v1beta1
+        hostPath:
+          path: \\.\pipe\csi-proxy-disk-v1beta1
+          type: ""
       - name: csi-proxy-disk-v1beta2
         hostPath:
           path: \\.\pipe\csi-proxy-disk-v1beta2
diff --git a/deploy/kubernetes/images/alpha/image.yaml b/deploy/kubernetes/images/alpha/image.yaml
index 84441ffb..8d7de688 100644
--- a/deploy/kubernetes/images/alpha/image.yaml
+++ b/deploy/kubernetes/images/alpha/image.yaml
@@ -4,7 +4,8 @@ metadata:
   name: imagetag-gcepd-driver-alpha-win
 imageTag:
   name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  newTag: "v1.2.0-gke.8"
+  newName: gcr.io/gke-release-staging/gcp-compute-persistent-disk-csi-driver
+  newTag: "v1.0.1-gke.9"
 ---
 
 apiVersion: builtin
@@ -12,5 +13,6 @@ kind: ImageTagTransformer
 metadata:
   name: imagetag-node-registrar-win
 imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
+  name: gke.gcr.io/k8s-staging-csi/csi-node-driver-registrar-win
+  newName: gcr.io/k8s-staging-csi/csi-node-driver-registrar
+  newTag: "amd64-windows-canary"
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-15/image.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-15/image.yaml
deleted file mode 100644
index f9b2ae85..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-15/image.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v1.6.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v2.2.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-gce-driver-prow-rc
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  newName: gcr.io/gke-release-staging/gcp-compute-persistent-disk-csi-driver
-  newTag: "v1.2.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-15/kustomization.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-15/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-15/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-16/image.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-16/image.yaml
deleted file mode 100644
index 7c2a4e05..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-16/image.yaml
+++ /dev/null
@@ -1,45 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v1.6.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v2.2.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resize-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.0.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-gce-driver-prow-rc
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  newName: gcr.io/gke-release-staging/gcp-compute-persistent-disk-csi-driver
-  newTag: "v1.2.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-16/kustomization.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-16/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-16/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-17/image.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-17/image.yaml
deleted file mode 100644
index e21efd80..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-17/image.yaml
+++ /dev/null
@@ -1,45 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resize-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-gce-driver-prow-rc
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  newName: gcr.io/gke-release-staging/gcp-compute-persistent-disk-csi-driver
-  newTag: "v1.2.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-17/kustomization.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-17/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-17/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-18/image.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-18/image.yaml
deleted file mode 100644
index 6acc3b9a..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-18/image.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resize-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-gce-driver-prow-rc
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  newName: gcr.io/gke-release-staging/gcp-compute-persistent-disk-csi-driver
-  newTag: "v1.2.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-snapshotter-prow-head
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
----
-
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-18/kustomization.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-18/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-18/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-19/image.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-19/image.yaml
deleted file mode 100644
index 6acc3b9a..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-19/image.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resize-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-gce-driver-prow-rc
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  newName: gcr.io/gke-release-staging/gcp-compute-persistent-disk-csi-driver
-  newTag: "v1.2.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-snapshotter-prow-head
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
----
-
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-19/kustomization.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-1-19/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-1-19/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-master/image.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-master/image.yaml
deleted file mode 100644
index 6acc3b9a..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-master/image.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resize-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-gce-driver-prow-rc
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  newName: gcr.io/gke-release-staging/gcp-compute-persistent-disk-csi-driver
-  newTag: "v1.2.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar-prow-rc
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-snapshotter-prow-head
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
----
-
diff --git a/deploy/kubernetes/images/prow-gke-release-staging-rc-master/kustomization.yaml b/deploy/kubernetes/images/prow-gke-release-staging-rc-master/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/prow-gke-release-staging-rc-master/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/stable-1-15/image.yaml b/deploy/kubernetes/images/stable-1-15/image.yaml
deleted file mode 100644
index 612d9347..00000000
--- a/deploy/kubernetes/images/stable-1-15/image.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v1.6.1"
-
----
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v2.2.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resizer
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.0.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-gcepd-driver
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  # Don't change stable image without changing pdImagePlaceholder in
-  # test/k8s-integration/main.go
-  newTag: "v1.2.0-gke.0"
----
diff --git a/deploy/kubernetes/images/stable-1-15/kustomization.yaml b/deploy/kubernetes/images/stable-1-15/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/stable-1-15/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/stable-1-16/image.yaml b/deploy/kubernetes/images/stable-1-16/image.yaml
deleted file mode 100644
index 612d9347..00000000
--- a/deploy/kubernetes/images/stable-1-16/image.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v1.6.1"
-
----
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v2.2.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resizer
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.0.1"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-gcepd-driver
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  # Don't change stable image without changing pdImagePlaceholder in
-  # test/k8s-integration/main.go
-  newTag: "v1.2.0-gke.0"
----
diff --git a/deploy/kubernetes/images/stable-1-16/kustomization.yaml b/deploy/kubernetes/images/stable-1-16/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/stable-1-16/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/stable-1-17/image.yaml b/deploy/kubernetes/images/stable-1-17/image.yaml
deleted file mode 100644
index b641cbe5..00000000
--- a/deploy/kubernetes/images/stable-1-17/image.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
-
----
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resizer
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-snapshotter
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-gcepd-driver
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  # Don't change stable image without changing pdImagePlaceholder in
-  # test/k8s-integration/main.go
-  newTag: "v1.2.0-gke.0"
----
diff --git a/deploy/kubernetes/images/stable-1-17/kustomization.yaml b/deploy/kubernetes/images/stable-1-17/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/stable-1-17/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/stable-1-18/image.yaml b/deploy/kubernetes/images/stable-1-18/image.yaml
deleted file mode 100644
index b641cbe5..00000000
--- a/deploy/kubernetes/images/stable-1-18/image.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
-
----
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resizer
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-snapshotter
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-gcepd-driver
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  # Don't change stable image without changing pdImagePlaceholder in
-  # test/k8s-integration/main.go
-  newTag: "v1.2.0-gke.0"
----
diff --git a/deploy/kubernetes/images/stable-1-18/kustomization.yaml b/deploy/kubernetes/images/stable-1-18/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/stable-1-18/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/stable-1-19/image.yaml b/deploy/kubernetes/images/stable-1-19/image.yaml
deleted file mode 100644
index b641cbe5..00000000
--- a/deploy/kubernetes/images/stable-1-19/image.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
-
----
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resizer
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-snapshotter
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-gcepd-driver
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  # Don't change stable image without changing pdImagePlaceholder in
-  # test/k8s-integration/main.go
-  newTag: "v1.2.0-gke.0"
----
diff --git a/deploy/kubernetes/images/stable-1-19/kustomization.yaml b/deploy/kubernetes/images/stable-1-19/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/stable-1-19/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/stable-master/image.yaml b/deploy/kubernetes/images/stable-master/image.yaml
deleted file mode 100644
index b641cbe5..00000000
--- a/deploy/kubernetes/images/stable-master/image.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-provisioner
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
-
----
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-attacher
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-resizer
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-snapshotter
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-csi-node-registrar
-imageTag:
-  name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
----
-
-apiVersion: builtin
-kind: ImageTagTransformer
-metadata:
-  name: imagetag-gcepd-driver
-imageTag:
-  name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
-  # Don't change stable image without changing pdImagePlaceholder in
-  # test/k8s-integration/main.go
-  newTag: "v1.2.0-gke.0"
----
diff --git a/deploy/kubernetes/images/stable-master/kustomization.yaml b/deploy/kubernetes/images/stable-master/kustomization.yaml
deleted file mode 100644
index f16988f1..00000000
--- a/deploy/kubernetes/images/stable-master/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace:
-  gce-pd-csi-driver
-resources:
-- image.yaml
diff --git a/deploy/kubernetes/images/stable/image.yaml b/deploy/kubernetes/images/stable/image.yaml
index 108eda3d..5814e03a 100644
--- a/deploy/kubernetes/images/stable/image.yaml
+++ b/deploy/kubernetes/images/stable/image.yaml
@@ -4,7 +4,7 @@ metadata:
   name: imagetag-csi-provisioner
 imageTag:
   name: k8s.gcr.io/sig-storage/csi-provisioner
-  newTag: "v2.1.0"
+  newTag: "v2.0.4"
 
 ---
 apiVersion: builtin
@@ -13,7 +13,7 @@ metadata:
   name: imagetag-csi-attacher
 imageTag:
   name: k8s.gcr.io/sig-storage/csi-attacher
-  newTag: "v3.1.0"
+  newTag: "v3.0.1"
 ---
 
 apiVersion: builtin
@@ -22,7 +22,7 @@ metadata:
   name: imagetag-csi-resizer
 imageTag:
   name: k8s.gcr.io/sig-storage/csi-resizer
-  newTag: "v1.1.0"
+  newTag: "v1.0.1"
 ---
 
 apiVersion: builtin
@@ -31,7 +31,7 @@ metadata:
   name: imagetag-csi-snapshotter
 imageTag:
   name: k8s.gcr.io/sig-storage/csi-snapshotter
-  newTag: "v3.0.3"
+  newTag: "v3.0.1"
 ---
 
 apiVersion: builtin
@@ -40,7 +40,7 @@ metadata:
   name: imagetag-csi-node-registrar
 imageTag:
   name: k8s.gcr.io/sig-storage/csi-node-driver-registrar
-  newTag: "v2.1.0"
+  newTag: "v2.0.1"
 ---
 
 apiVersion: builtin
@@ -51,5 +51,5 @@ imageTag:
   name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
   # Don't change stable image without changing pdImagePlaceholder in
   # test/k8s-integration/main.go
-  newTag: "v1.2.0-gke.8"
+  newTag: "v1.2.0-gke.0"
 ---
diff --git a/deploy/kubernetes/install-kustomize.sh b/deploy/kubernetes/install-kustomize.sh
index 49d2a806..792e41d7 100755
--- a/deploy/kubernetes/install-kustomize.sh
+++ b/deploy/kubernetes/install-kustomize.sh
@@ -50,7 +50,7 @@ curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases |\
   grep browser_download |\
   grep $opsys |\
   cut -d '"' -f 4 |\
-  grep /kustomize/v3.9.4 |\
+  grep /kustomize/v3.8.6 |\
   sort | tail -n 1 |\
   xargs curl -s -O -L
 
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-15/README.md b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-15/README.md
deleted file mode 100644
index de722221..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-15/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-These overlays are intended to be only used by prow for CI testing.
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-15/kustomization.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-15/kustomization.yaml
deleted file mode 100644
index 5489ff0f..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-15/kustomization.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-resources:
-- ../stable-1-15
-transformers:
-- ../../images/prow-gke-release-staging-rc-1-15
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-16/README.md b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-16/README.md
deleted file mode 100644
index de722221..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-16/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-These overlays are intended to be only used by prow for CI testing.
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-16/kustomization.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-16/kustomization.yaml
deleted file mode 100644
index 96515ea0..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-16/kustomization.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-resources:
-- ../stable-1-16
-transformers:
-- ../../images/prow-gke-release-staging-rc-1-16
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-17/README.md b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-17/README.md
deleted file mode 100644
index de722221..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-17/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-These overlays are intended to be only used by prow for CI testing.
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-17/kustomization.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-17/kustomization.yaml
deleted file mode 100644
index 71dde210..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-17/kustomization.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-resources:
-- ../stable-1-17
-transformers:
-- ../../images/prow-gke-release-staging-rc-1-17
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-18/README.md b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-18/README.md
deleted file mode 100644
index de722221..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-18/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-These overlays are intended to be only used by prow for CI testing.
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-18/kustomization.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-18/kustomization.yaml
deleted file mode 100644
index 83e11bd4..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-18/kustomization.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-resources:
-- ../stable-1-18
-transformers:
-- ../../images/prow-gke-release-staging-rc-1-18
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-19/README.md b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-19/README.md
deleted file mode 100644
index de722221..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-19/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-These overlays are intended to be only used by prow for CI testing.
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-19/kustomization.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-19/kustomization.yaml
deleted file mode 100644
index 1390db41..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-1-19/kustomization.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-resources:
-- ../stable-1-19
-transformers:
-- ../../images/prow-gke-release-staging-rc-1-19
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-master/README.md b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-master/README.md
deleted file mode 100644
index de722221..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-master/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-These overlays are intended to be only used by prow for CI testing.
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-master/kustomization.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc-master/kustomization.yaml
deleted file mode 100644
index 39849726..00000000
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc-master/kustomization.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-resources:
-- ../stable-master
-transformers:
-- ../../images/prow-gke-release-staging-rc-master
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc/controller_patches.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc/controller_patches.yaml
new file mode 100644
index 00000000..2feb0ba9
--- /dev/null
+++ b/deploy/kubernetes/overlays/prow-gke-release-staging-rc/controller_patches.yaml
@@ -0,0 +1,62 @@
+# for external-provisioner
+- op: replace
+  path: /spec/template/spec/containers/0/args/3
+  value: "--http-endpoint=:22011"
+- op: add
+  path: /spec/template/spec/containers/0/ports
+  value:
+  - containerPort: 22011
+    name: http-endpoint
+    protocol: TCP
+- op: add
+  path: /spec/template/spec/containers/0/livenessProbe
+  value:
+    failureThreshold: 1
+    httpGet:
+      path: /healthz/leader-election
+      port: http-endpoint
+    initialDelaySeconds: 10
+    timeoutSeconds: 10
+    periodSeconds: 20
+
+# for external-attacher
+- op: replace
+  path: /spec/template/spec/containers/1/args/2
+  value: "--http-endpoint=:22012"
+- op: add
+  path: /spec/template/spec/containers/1/ports
+  value:
+  - containerPort: 22012
+    name: http-endpoint
+    protocol: TCP
+- op: add
+  path: /spec/template/spec/containers/1/livenessProbe
+  value:
+    failureThreshold: 1
+    httpGet:
+      path: /healthz/leader-election
+      port: http-endpoint
+    initialDelaySeconds: 10
+    timeoutSeconds: 10
+    periodSeconds: 20
+
+# for external-resizer
+- op: replace
+  path: /spec/template/spec/containers/2/args/2
+  value: "--http-endpoint=:22013"
+- op: add
+  path: /spec/template/spec/containers/2/ports
+  value:
+  - containerPort: 22013
+    name: http-endpoint
+    protocol: TCP
+- op: add
+  path: /spec/template/spec/containers/2/livenessProbe
+  value:
+    failureThreshold: 1
+    httpGet:
+      path: /healthz/leader-election
+      port: http-endpoint
+    initialDelaySeconds: 10
+    timeoutSeconds: 10
+    periodSeconds: 20
diff --git a/deploy/kubernetes/overlays/prow-gke-release-staging-rc/kustomization.yaml b/deploy/kubernetes/overlays/prow-gke-release-staging-rc/kustomization.yaml
index 64418666..bf28e23c 100644
--- a/deploy/kubernetes/overlays/prow-gke-release-staging-rc/kustomization.yaml
+++ b/deploy/kubernetes/overlays/prow-gke-release-staging-rc/kustomization.yaml
@@ -4,3 +4,10 @@ resources:
 - ../stable
 transformers:
 - ../../images/prow-gke-release-staging-rc
+patchesJson6902:
+- target:
+    group: apps
+    version: v1
+    kind: Deployment
+    name: csi-gce-pd-controller
+  path: controller_patches.yaml
diff --git a/deploy/kubernetes/overlays/stable-1-15/kustomization.yaml b/deploy/kubernetes/overlays/stable-1-15/kustomization.yaml
deleted file mode 100644
index d39d41ed..00000000
--- a/deploy/kubernetes/overlays/stable-1-15/kustomization.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-namespace:
-  gce-pd-csi-driver
-resources:
-- ../../base/controller
-- ../../base/node_linux
-patchesStrategicMerge:
-- no_resizer_snapshotter_sidecar.yaml
-- no_resizer_snapshotter_roles.yaml
-- no_win_roles.yaml
-patchesJson6902:
-- target:
-    group: apps
-    version: v1
-    kind: Deployment
-    name: csi-gce-pd-controller
-  path: metrics_leaderelection_endpoint.yaml
-transformers:
-- ../../images/stable-1-15
diff --git a/deploy/kubernetes/overlays/stable-1-15/metrics_leaderelection_endpoint.yaml b/deploy/kubernetes/overlays/stable-1-15/metrics_leaderelection_endpoint.yaml
deleted file mode 100644
index 47eedc07..00000000
--- a/deploy/kubernetes/overlays/stable-1-15/metrics_leaderelection_endpoint.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-# for external-provisioner
-- op: replace
-  path: /spec/template/spec/containers/0/args/3
-  value: "--metrics-address=:22011"
-- op: replace
-  path: /spec/template/spec/containers/0/args/7
-  value: "--enable-leader-election"
-- op: replace
-  path: /spec/template/spec/containers/0/args/8
-  value: "--leader-election-type=leases"
-- op: remove
-  path: /spec/template/spec/containers/0/ports
-- op: remove
-  path: /spec/template/spec/containers/0/livenessProbe
-# for external-attacher
-- op: replace
-  path: /spec/template/spec/containers/1/args/2
-  value: "--metrics-address=:22012"
-- op: remove
-  path: /spec/template/spec/containers/1/ports
-- op: remove
-  path: /spec/template/spec/containers/1/livenessProbe
diff --git a/deploy/kubernetes/overlays/stable-1-15/no_resizer_snapshotter_roles.yaml b/deploy/kubernetes/overlays/stable-1-15/no_resizer_snapshotter_roles.yaml
deleted file mode 100644
index 0bbddd59..00000000
--- a/deploy/kubernetes/overlays/stable-1-15/no_resizer_snapshotter_roles.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-$patch: delete
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-resizer-role
-
----
-$patch: delete
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-resizer-binding
----
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  name: csi-gce-pd-snapshotter-role
----
-$patch: delete
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-controller-snapshotter-binding
----
diff --git a/deploy/kubernetes/overlays/stable-1-15/no_resizer_snapshotter_sidecar.yaml b/deploy/kubernetes/overlays/stable-1-15/no_resizer_snapshotter_sidecar.yaml
deleted file mode 100644
index 96abdce4..00000000
--- a/deploy/kubernetes/overlays/stable-1-15/no_resizer_snapshotter_sidecar.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-kind: Deployment
-apiVersion: apps/v1
-metadata:
-  name: csi-gce-pd-controller
-spec:
-  template:
-    spec:
-      containers:
-        - $patch: delete
-          name: csi-resizer
-        - $patch: delete
-          name: csi-snapshotter
diff --git a/deploy/kubernetes/overlays/stable-1-15/no_win_roles.yaml b/deploy/kubernetes/overlays/stable-1-15/no_win_roles.yaml
deleted file mode 100644
index 0d9bc051..00000000
--- a/deploy/kubernetes/overlays/stable-1-15/no_win_roles.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-$patch: delete
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: csi-gce-pd-node-sa-win
----
-$patch: delete
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-node-deploy-win
----
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  name: csi-gce-pd-node-win
diff --git a/deploy/kubernetes/overlays/stable-1-16/kustomization.yaml b/deploy/kubernetes/overlays/stable-1-16/kustomization.yaml
deleted file mode 100644
index 52e12d60..00000000
--- a/deploy/kubernetes/overlays/stable-1-16/kustomization.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-namespace:
-  gce-pd-csi-driver
-resources:
-- ../../base/controller
-- ../../base/node_linux
-patchesStrategicMerge:
-- no_snapshotter_sidecar.yaml
-- no_snapshotter_roles.yaml
-- no_win_roles.yaml
-patchesJson6902:
-- target:
-    group: apps
-    version: v1
-    kind: Deployment
-    name: csi-gce-pd-controller
-  path: metrics_leaderelection_endpoint.yaml
-transformers:
-- ../../images/stable-1-16
diff --git a/deploy/kubernetes/overlays/stable-1-16/metrics_leaderelection_endpoint.yaml b/deploy/kubernetes/overlays/stable-1-16/metrics_leaderelection_endpoint.yaml
deleted file mode 100644
index 8aea5421..00000000
--- a/deploy/kubernetes/overlays/stable-1-16/metrics_leaderelection_endpoint.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-# for external-provisioner
-- op: replace
-  path: /spec/template/spec/containers/0/args/3
-  value: "--metrics-address=:22011"
-- op: replace
-  path: /spec/template/spec/containers/0/args/7
-  value: "--enable-leader-election"
-- op: replace
-  path: /spec/template/spec/containers/0/args/8
-  value: "--leader-election-type=leases"
-- op: remove
-  path: /spec/template/spec/containers/0/ports
-- op: remove
-  path: /spec/template/spec/containers/0/livenessProbe
-# for external-attacher
-- op: replace
-  path: /spec/template/spec/containers/1/args/2
-  value: "--metrics-address=:22012"
-- op: remove
-  path: /spec/template/spec/containers/1/ports
-- op: remove
-  path: /spec/template/spec/containers/1/livenessProbe
-# for external-resizer
-- op: replace
-  path: /spec/template/spec/containers/2/args/2
-  value: "--metrics-address=:22013"
-- op: remove
-  path: /spec/template/spec/containers/2/ports
-- op: remove
-  path: /spec/template/spec/containers/2/livenessProbe
diff --git a/deploy/kubernetes/overlays/stable-1-16/no_snapshotter_roles.yaml b/deploy/kubernetes/overlays/stable-1-16/no_snapshotter_roles.yaml
deleted file mode 100644
index a619feca..00000000
--- a/deploy/kubernetes/overlays/stable-1-16/no_snapshotter_roles.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-# TODO: Check if we can remove the snapshot, snapshotcontent get list roles for provisioner
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  name: csi-gce-pd-snapshotter-role
----
-$patch: delete
-kind: ClusterRoleBinding
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-controller-snapshotter-binding
----
diff --git a/deploy/kubernetes/overlays/stable-1-16/no_snapshotter_sidecar.yaml b/deploy/kubernetes/overlays/stable-1-16/no_snapshotter_sidecar.yaml
deleted file mode 100644
index 61805910..00000000
--- a/deploy/kubernetes/overlays/stable-1-16/no_snapshotter_sidecar.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-kind: Deployment
-apiVersion: apps/v1
-metadata:
-  name: csi-gce-pd-controller
-spec:
-  template:
-    spec:
-      containers:
-        - $patch: delete
-          name: csi-snapshotter
diff --git a/deploy/kubernetes/overlays/stable-1-16/no_win_roles.yaml b/deploy/kubernetes/overlays/stable-1-16/no_win_roles.yaml
deleted file mode 100644
index 0d9bc051..00000000
--- a/deploy/kubernetes/overlays/stable-1-16/no_win_roles.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-$patch: delete
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: csi-gce-pd-node-sa-win
----
-$patch: delete
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-node-deploy-win
----
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  name: csi-gce-pd-node-win
diff --git a/deploy/kubernetes/overlays/stable-1-17/kustomization.yaml b/deploy/kubernetes/overlays/stable-1-17/kustomization.yaml
deleted file mode 100644
index 9021962c..00000000
--- a/deploy/kubernetes/overlays/stable-1-17/kustomization.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-namespace:
-  gce-pd-csi-driver
-resources:
-- ../../base/controller
-- ../../base/node_linux
-patchesStrategicMerge:
-- no_win_roles.yaml
-transformers:
-- ../../images/stable-1-17
diff --git a/deploy/kubernetes/overlays/stable-1-17/no_win_roles.yaml b/deploy/kubernetes/overlays/stable-1-17/no_win_roles.yaml
deleted file mode 100644
index 0d9bc051..00000000
--- a/deploy/kubernetes/overlays/stable-1-17/no_win_roles.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-$patch: delete
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: csi-gce-pd-node-sa-win
----
-$patch: delete
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-node-deploy-win
----
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  name: csi-gce-pd-node-win
diff --git a/deploy/kubernetes/overlays/stable-1-18/kustomization.yaml b/deploy/kubernetes/overlays/stable-1-18/kustomization.yaml
deleted file mode 100644
index be4221ae..00000000
--- a/deploy/kubernetes/overlays/stable-1-18/kustomization.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-namespace:
-  gce-pd-csi-driver
-resources:
-- ../../base/controller
-- ../../base/node_linux
-patchesStrategicMerge:
-- no_win_roles.yaml
-transformers:
-- ../../images/stable-1-18
diff --git a/deploy/kubernetes/overlays/stable-1-18/no_win_roles.yaml b/deploy/kubernetes/overlays/stable-1-18/no_win_roles.yaml
deleted file mode 100644
index 0d9bc051..00000000
--- a/deploy/kubernetes/overlays/stable-1-18/no_win_roles.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-$patch: delete
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: csi-gce-pd-node-sa-win
----
-$patch: delete
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-node-deploy-win
----
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  name: csi-gce-pd-node-win
diff --git a/deploy/kubernetes/overlays/stable-1-19/kustomization.yaml b/deploy/kubernetes/overlays/stable-1-19/kustomization.yaml
deleted file mode 100644
index 1134a03e..00000000
--- a/deploy/kubernetes/overlays/stable-1-19/kustomization.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-namespace:
-  gce-pd-csi-driver
-resources:
-- ../../base/controller
-- ../../base/node_linux
-patchesStrategicMerge:
-- no_win_roles.yaml
-transformers:
-- ../../images/stable-1-19
diff --git a/deploy/kubernetes/overlays/stable-1-19/no_win_roles.yaml b/deploy/kubernetes/overlays/stable-1-19/no_win_roles.yaml
deleted file mode 100644
index 0d9bc051..00000000
--- a/deploy/kubernetes/overlays/stable-1-19/no_win_roles.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-$patch: delete
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: csi-gce-pd-node-sa-win
----
-$patch: delete
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-node-deploy-win
----
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  name: csi-gce-pd-node-win
diff --git a/deploy/kubernetes/overlays/stable-master/kustomization.yaml b/deploy/kubernetes/overlays/stable-master/kustomization.yaml
deleted file mode 100644
index 1b8407a0..00000000
--- a/deploy/kubernetes/overlays/stable-master/kustomization.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-namespace:
-  gce-pd-csi-driver
-resources:
-- ../../base/controller
-- ../../base/node_linux
-patchesStrategicMerge:
-- no_win_roles.yaml
-transformers:
-- ../../images/stable-master
diff --git a/deploy/kubernetes/overlays/stable-master/no_win_roles.yaml b/deploy/kubernetes/overlays/stable-master/no_win_roles.yaml
deleted file mode 100644
index 0d9bc051..00000000
--- a/deploy/kubernetes/overlays/stable-master/no_win_roles.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-$patch: delete
-apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: csi-gce-pd-node-sa-win
----
-$patch: delete
-kind: ClusterRole
-apiVersion: rbac.authorization.k8s.io/v1
-metadata:
-  name: csi-gce-pd-node-deploy-win
----
-$patch: delete
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  name: csi-gce-pd-node-win
diff --git a/deploy/kubernetes/overlays/stable/kustomization.yaml b/deploy/kubernetes/overlays/stable/kustomization.yaml
index fbdbb235..7adc4e4b 100644
--- a/deploy/kubernetes/overlays/stable/kustomization.yaml
+++ b/deploy/kubernetes/overlays/stable/kustomization.yaml
@@ -3,6 +3,7 @@ kind: Kustomization
 namespace:
   gce-pd-csi-driver
 resources:
-- ../../base/
+- ../../base/controller
+- ../../base/node_linux
 transformers:
 - ../../images/stable
diff --git a/go.mod b/go.mod
index 38802d84..dc4f02f6 100644
--- a/go.mod
+++ b/go.mod
@@ -23,6 +23,7 @@ require (
 	gopkg.in/warnings.v0 v0.1.2 // indirect
 	k8s.io/apimachinery v0.18.0
 	k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
+	k8s.io/component-base v0.18.0
 	k8s.io/klog v1.0.0
 	k8s.io/kubernetes v1.18.0
 	k8s.io/test-infra v0.0.0-20200115230622-70a5174aa78d
diff --git a/go.sum b/go.sum
index 3370814e..91cb9240 100644
--- a/go.sum
+++ b/go.sum
@@ -476,9 +476,6 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kubernetes-csi/csi-proxy v0.2.2 h1:LqablYFEGw7FYBjwoh5TeXFzlcx8C+YQjKfGy6fFWJs=
-github.com/kubernetes-csi/csi-proxy/client v0.2.1 h1:n21d2U9HvgQ6jfJayafRv8kXXtLvnRNEqoD0mQNucKc=
-github.com/kubernetes-csi/csi-proxy/client v0.2.1/go.mod h1:6ptQQmti5QHwBxSsh8Cy00oGdogj0JXewFnu8FFjgOs=
 github.com/kubernetes-csi/csi-proxy/client v0.2.2 h1:VpMddHnbYA1oBeU5nrisdyrpOAAT0HqME7fsTi6BG2w=
 github.com/kubernetes-csi/csi-proxy/client v0.2.2/go.mod h1:6ptQQmti5QHwBxSsh8Cy00oGdogj0JXewFnu8FFjgOs=
 github.com/kubernetes-csi/csi-test/v3 v3.0.0 h1:mVsfA4J67uNm8fdF/Pr84oMqL92qjIhjWbEUH8zv1fU=
@@ -1149,6 +1146,7 @@ k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
 k8s.io/cloud-provider v0.18.0/go.mod h1:ZBq1FhoJ+XoQ8JYBYoyx81LS3JV0RAW/UmHf/6w9E6k=
 k8s.io/cluster-bootstrap v0.18.0/go.mod h1:xSe+bOZ3asS/ciT91ESQYGhjOql43aBETfvbCzNvad8=
 k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
+k8s.io/component-base v0.18.0 h1:I+lP0fNfsEdTDpHaL61bCAqTZLoiWjEEP304Mo5ZQgE=
 k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c=
 k8s.io/cri-api v0.18.0/go.mod h1:OJtpjDvfsKoLGhvcc0qfygved0S0dGX56IJzPbqTG1s=
 k8s.io/csi-translation-lib v0.18.0/go.mod h1:iF8TE4ACSaPqN1qxmiIjvcU1A8VgkOrpcFGD7Z0hVu0=
diff --git a/hack/verify-coverage.sh b/hack/verify-coverage.sh
deleted file mode 100755
index 7fb63055..00000000
--- a/hack/verify-coverage.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2021 The Kubernetes 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.
-
-set -o errexit
-set -o nounset
-set -o pipefail
-
-PKG_ROOT=$(realpath $(dirname "${BASH_SOURCE[0]}")/..)
-
-testdirs() {
-  find -L "${PKG_ROOT}" -not \( \
-      \( \
-        -path "${PKG_ROOT}"/vendor/\* \
-        -o -path "${PKG_ROOT}"/test/\* \) \
-      -prune \) \
-    -name \*_test.go -print0 | xargs -0n1 dirname | \
-    sed "s|^${PKG_ROOT}/|./|" | LC_ALL=C sort -u
-}
-
-coverprofile=${1-"${PKG_ROOT}"/coverage_gcp-compute-persistent-disk-csi-driver.out}
-if [[ -z $coverprofile ]]; then
-  echo "usage: ./hack/verify-coverage.sh <coverprofile>"
-  exit 1
-fi
-
-if [[ x"${coverprofile:(-4)}" != x.out ]] ; then
-  echo "coverprofile ${coverprofile} must end in .out"
-  exit 1
-fi
-
-# Remove any old cover profile so that the run is clean.
-rm -f "${coverprofile}"
-
-echo "Verifying coverage"
-go test -coverprofile="${coverprofile}" $(testdirs)
diff --git a/pkg/common/parameters.go b/pkg/common/parameters.go
index 5035bc5e..b8d1f556 100644
--- a/pkg/common/parameters.go
+++ b/pkg/common/parameters.go
@@ -54,16 +54,20 @@ type DiskParameters struct {
 	// Values: {map[string]string}
 	// Default: ""
 	Tags map[string]string
+	// Values: {map[string]string}
+	// Default: ""
+	Labels map[string]string
 }
 
 // ExtractAndDefaultParameters will take the relevant parameters from a map and
 // put them into a well defined struct making sure to default unspecified fields
-func ExtractAndDefaultParameters(parameters map[string]string, driverName string) (DiskParameters, error) {
+func ExtractAndDefaultParameters(parameters map[string]string, driverName string, extraVolumeLabels map[string]string) (DiskParameters, error) {
 	p := DiskParameters{
 		DiskType:             "pd-standard",           // Default
 		ReplicationType:      replicationTypeNone,     // Default
 		DiskEncryptionKMSKey: "",                      // Default
 		Tags:                 make(map[string]string), // Default
+		Labels:               make(map[string]string), // Default
 	}
 
 	for k, v := range parameters {
@@ -96,5 +100,8 @@ func ExtractAndDefaultParameters(parameters map[string]string, driverName string
 	if len(p.Tags) > 0 {
 		p.Tags[tagKeyCreatedBy] = driverName
 	}
+	for k, v := range extraVolumeLabels {
+		p.Labels[k] = v
+	}
 	return p, nil
 }
diff --git a/pkg/gce-cloud-provider/compute/gce-compute.go b/pkg/gce-cloud-provider/compute/gce-compute.go
index 760f5a40..3a460e4b 100644
--- a/pkg/gce-cloud-provider/compute/gce-compute.go
+++ b/pkg/gce-cloud-provider/compute/gce-compute.go
@@ -477,6 +477,7 @@ func (cloud *CloudProvider) insertZonalDisk(
 		SizeGb:      common.BytesToGbRoundUp(capBytes),
 		Description: description,
 		Type:        cloud.GetDiskTypeURI(volKey, params.DiskType),
+		Labels:      params.Labels,
 	}
 
 	if snapshotID != "" {
diff --git a/pkg/gce-pd-csi-driver/controller.go b/pkg/gce-pd-csi-driver/controller.go
index 5d164db2..bdf2042e 100644
--- a/pkg/gce-pd-csi-driver/controller.go
+++ b/pkg/gce-pd-csi-driver/controller.go
@@ -107,7 +107,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
 
 	// Apply Parameters (case-insensitive). We leave validation of
 	// the values to the cloud provider.
-	params, err := common.ExtractAndDefaultParameters(req.GetParameters(), gceCS.Driver.name)
+	params, err := common.ExtractAndDefaultParameters(req.GetParameters(), gceCS.Driver.name, gceCS.Driver.extraVolumeLabels)
 	if err != nil {
 		return nil, status.Errorf(codes.InvalidArgument, "failed to extract parameters: %v", err)
 	}
@@ -475,7 +475,7 @@ func (gceCS *GCEControllerServer) ValidateVolumeCapabilities(ctx context.Context
 	}
 
 	// Validate the disk parameters match the disk we GET
-	params, err := common.ExtractAndDefaultParameters(req.GetParameters(), gceCS.Driver.name)
+	params, err := common.ExtractAndDefaultParameters(req.GetParameters(), gceCS.Driver.name, gceCS.Driver.extraVolumeLabels)
 	if err != nil {
 		return nil, status.Errorf(codes.InvalidArgument, "failed to extract parameters: %v", err)
 	}
diff --git a/pkg/gce-pd-csi-driver/gce-pd-driver.go b/pkg/gce-pd-csi-driver/gce-pd-driver.go
index 92c12cbc..45903f33 100644
--- a/pkg/gce-pd-csi-driver/gce-pd-driver.go
+++ b/pkg/gce-pd-csi-driver/gce-pd-driver.go
@@ -29,8 +29,9 @@ import (
 )
 
 type GCEDriver struct {
-	name          string
-	vendorVersion string
+	name              string
+	vendorVersion     string
+	extraVolumeLabels map[string]string
 
 	ids *GCEIdentityServer
 	ns  *GCENodeServer
@@ -45,7 +46,7 @@ func GetGCEDriver() *GCEDriver {
 	return &GCEDriver{}
 }
 
-func (gceDriver *GCEDriver) SetupGCEDriver(name, vendorVersion string, identityServer *GCEIdentityServer, controllerServer *GCEControllerServer, nodeServer *GCENodeServer) error {
+func (gceDriver *GCEDriver) SetupGCEDriver(name, vendorVersion string, extraVolumeLabels map[string]string, identityServer *GCEIdentityServer, controllerServer *GCEControllerServer, nodeServer *GCENodeServer) error {
 	if name == "" {
 		return fmt.Errorf("Driver name missing")
 	}
@@ -77,6 +78,7 @@ func (gceDriver *GCEDriver) SetupGCEDriver(name, vendorVersion string, identityS
 
 	gceDriver.name = name
 	gceDriver.vendorVersion = vendorVersion
+	gceDriver.extraVolumeLabels = extraVolumeLabels
 	gceDriver.ids = identityServer
 	gceDriver.cs = controllerServer
 	gceDriver.ns = nodeServer
diff --git a/vendor/github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1/api.pb.go b/vendor/github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1/api.pb.go
deleted file mode 100644
index 099b9769..00000000
--- a/vendor/github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1/api.pb.go
+++ /dev/null
@@ -1,779 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: disk/v1beta1/api.proto
-
-package v1beta1
-
-import (
-	context "context"
-	fmt "fmt"
-	proto "github.com/golang/protobuf/proto"
-	grpc "google.golang.org/grpc"
-	codes "google.golang.org/grpc/codes"
-	status "google.golang.org/grpc/status"
-	math "math"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
-
-type ListDiskLocationsRequest struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ListDiskLocationsRequest) Reset()         { *m = ListDiskLocationsRequest{} }
-func (m *ListDiskLocationsRequest) String() string { return proto.CompactTextString(m) }
-func (*ListDiskLocationsRequest) ProtoMessage()    {}
-func (*ListDiskLocationsRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{0}
-}
-
-func (m *ListDiskLocationsRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ListDiskLocationsRequest.Unmarshal(m, b)
-}
-func (m *ListDiskLocationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ListDiskLocationsRequest.Marshal(b, m, deterministic)
-}
-func (m *ListDiskLocationsRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ListDiskLocationsRequest.Merge(m, src)
-}
-func (m *ListDiskLocationsRequest) XXX_Size() int {
-	return xxx_messageInfo_ListDiskLocationsRequest.Size(m)
-}
-func (m *ListDiskLocationsRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_ListDiskLocationsRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ListDiskLocationsRequest proto.InternalMessageInfo
-
-type DiskLocation struct {
-	Adapter              string   `protobuf:"bytes,1,opt,name=Adapter,proto3" json:"Adapter,omitempty"`
-	Bus                  string   `protobuf:"bytes,2,opt,name=Bus,proto3" json:"Bus,omitempty"`
-	Target               string   `protobuf:"bytes,3,opt,name=Target,proto3" json:"Target,omitempty"`
-	LUNID                string   `protobuf:"bytes,4,opt,name=LUNID,proto3" json:"LUNID,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *DiskLocation) Reset()         { *m = DiskLocation{} }
-func (m *DiskLocation) String() string { return proto.CompactTextString(m) }
-func (*DiskLocation) ProtoMessage()    {}
-func (*DiskLocation) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{1}
-}
-
-func (m *DiskLocation) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_DiskLocation.Unmarshal(m, b)
-}
-func (m *DiskLocation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_DiskLocation.Marshal(b, m, deterministic)
-}
-func (m *DiskLocation) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_DiskLocation.Merge(m, src)
-}
-func (m *DiskLocation) XXX_Size() int {
-	return xxx_messageInfo_DiskLocation.Size(m)
-}
-func (m *DiskLocation) XXX_DiscardUnknown() {
-	xxx_messageInfo_DiskLocation.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_DiskLocation proto.InternalMessageInfo
-
-func (m *DiskLocation) GetAdapter() string {
-	if m != nil {
-		return m.Adapter
-	}
-	return ""
-}
-
-func (m *DiskLocation) GetBus() string {
-	if m != nil {
-		return m.Bus
-	}
-	return ""
-}
-
-func (m *DiskLocation) GetTarget() string {
-	if m != nil {
-		return m.Target
-	}
-	return ""
-}
-
-func (m *DiskLocation) GetLUNID() string {
-	if m != nil {
-		return m.LUNID
-	}
-	return ""
-}
-
-type ListDiskLocationsResponse struct {
-	// Map of disk device IDs and <adapter, bus, target, lun ID> associated with each disk device
-	DiskLocations        map[string]*DiskLocation `protobuf:"bytes,1,rep,name=disk_locations,json=diskLocations,proto3" json:"disk_locations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
-	XXX_unrecognized     []byte                   `json:"-"`
-	XXX_sizecache        int32                    `json:"-"`
-}
-
-func (m *ListDiskLocationsResponse) Reset()         { *m = ListDiskLocationsResponse{} }
-func (m *ListDiskLocationsResponse) String() string { return proto.CompactTextString(m) }
-func (*ListDiskLocationsResponse) ProtoMessage()    {}
-func (*ListDiskLocationsResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{2}
-}
-
-func (m *ListDiskLocationsResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ListDiskLocationsResponse.Unmarshal(m, b)
-}
-func (m *ListDiskLocationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ListDiskLocationsResponse.Marshal(b, m, deterministic)
-}
-func (m *ListDiskLocationsResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ListDiskLocationsResponse.Merge(m, src)
-}
-func (m *ListDiskLocationsResponse) XXX_Size() int {
-	return xxx_messageInfo_ListDiskLocationsResponse.Size(m)
-}
-func (m *ListDiskLocationsResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_ListDiskLocationsResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ListDiskLocationsResponse proto.InternalMessageInfo
-
-func (m *ListDiskLocationsResponse) GetDiskLocations() map[string]*DiskLocation {
-	if m != nil {
-		return m.DiskLocations
-	}
-	return nil
-}
-
-type PartitionDiskRequest struct {
-	// Disk device ID of the disk to partition
-	DiskID               string   `protobuf:"bytes,1,opt,name=diskID,proto3" json:"diskID,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PartitionDiskRequest) Reset()         { *m = PartitionDiskRequest{} }
-func (m *PartitionDiskRequest) String() string { return proto.CompactTextString(m) }
-func (*PartitionDiskRequest) ProtoMessage()    {}
-func (*PartitionDiskRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{3}
-}
-
-func (m *PartitionDiskRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PartitionDiskRequest.Unmarshal(m, b)
-}
-func (m *PartitionDiskRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PartitionDiskRequest.Marshal(b, m, deterministic)
-}
-func (m *PartitionDiskRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PartitionDiskRequest.Merge(m, src)
-}
-func (m *PartitionDiskRequest) XXX_Size() int {
-	return xxx_messageInfo_PartitionDiskRequest.Size(m)
-}
-func (m *PartitionDiskRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_PartitionDiskRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PartitionDiskRequest proto.InternalMessageInfo
-
-func (m *PartitionDiskRequest) GetDiskID() string {
-	if m != nil {
-		return m.DiskID
-	}
-	return ""
-}
-
-type PartitionDiskResponse struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PartitionDiskResponse) Reset()         { *m = PartitionDiskResponse{} }
-func (m *PartitionDiskResponse) String() string { return proto.CompactTextString(m) }
-func (*PartitionDiskResponse) ProtoMessage()    {}
-func (*PartitionDiskResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{4}
-}
-
-func (m *PartitionDiskResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PartitionDiskResponse.Unmarshal(m, b)
-}
-func (m *PartitionDiskResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PartitionDiskResponse.Marshal(b, m, deterministic)
-}
-func (m *PartitionDiskResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PartitionDiskResponse.Merge(m, src)
-}
-func (m *PartitionDiskResponse) XXX_Size() int {
-	return xxx_messageInfo_PartitionDiskResponse.Size(m)
-}
-func (m *PartitionDiskResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_PartitionDiskResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PartitionDiskResponse proto.InternalMessageInfo
-
-type RescanRequest struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *RescanRequest) Reset()         { *m = RescanRequest{} }
-func (m *RescanRequest) String() string { return proto.CompactTextString(m) }
-func (*RescanRequest) ProtoMessage()    {}
-func (*RescanRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{5}
-}
-
-func (m *RescanRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_RescanRequest.Unmarshal(m, b)
-}
-func (m *RescanRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_RescanRequest.Marshal(b, m, deterministic)
-}
-func (m *RescanRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_RescanRequest.Merge(m, src)
-}
-func (m *RescanRequest) XXX_Size() int {
-	return xxx_messageInfo_RescanRequest.Size(m)
-}
-func (m *RescanRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_RescanRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_RescanRequest proto.InternalMessageInfo
-
-type RescanResponse struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *RescanResponse) Reset()         { *m = RescanResponse{} }
-func (m *RescanResponse) String() string { return proto.CompactTextString(m) }
-func (*RescanResponse) ProtoMessage()    {}
-func (*RescanResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{6}
-}
-
-func (m *RescanResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_RescanResponse.Unmarshal(m, b)
-}
-func (m *RescanResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_RescanResponse.Marshal(b, m, deterministic)
-}
-func (m *RescanResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_RescanResponse.Merge(m, src)
-}
-func (m *RescanResponse) XXX_Size() int {
-	return xxx_messageInfo_RescanResponse.Size(m)
-}
-func (m *RescanResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_RescanResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_RescanResponse proto.InternalMessageInfo
-
-type ListDiskIDsRequest struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ListDiskIDsRequest) Reset()         { *m = ListDiskIDsRequest{} }
-func (m *ListDiskIDsRequest) String() string { return proto.CompactTextString(m) }
-func (*ListDiskIDsRequest) ProtoMessage()    {}
-func (*ListDiskIDsRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{7}
-}
-
-func (m *ListDiskIDsRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ListDiskIDsRequest.Unmarshal(m, b)
-}
-func (m *ListDiskIDsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ListDiskIDsRequest.Marshal(b, m, deterministic)
-}
-func (m *ListDiskIDsRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ListDiskIDsRequest.Merge(m, src)
-}
-func (m *ListDiskIDsRequest) XXX_Size() int {
-	return xxx_messageInfo_ListDiskIDsRequest.Size(m)
-}
-func (m *ListDiskIDsRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_ListDiskIDsRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ListDiskIDsRequest proto.InternalMessageInfo
-
-type DiskIDs struct {
-	// Map of Disk ID types and Disk ID values
-	Identifiers          map[string]string `protobuf:"bytes,1,rep,name=identifiers,proto3" json:"identifiers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
-	XXX_unrecognized     []byte            `json:"-"`
-	XXX_sizecache        int32             `json:"-"`
-}
-
-func (m *DiskIDs) Reset()         { *m = DiskIDs{} }
-func (m *DiskIDs) String() string { return proto.CompactTextString(m) }
-func (*DiskIDs) ProtoMessage()    {}
-func (*DiskIDs) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{8}
-}
-
-func (m *DiskIDs) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_DiskIDs.Unmarshal(m, b)
-}
-func (m *DiskIDs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_DiskIDs.Marshal(b, m, deterministic)
-}
-func (m *DiskIDs) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_DiskIDs.Merge(m, src)
-}
-func (m *DiskIDs) XXX_Size() int {
-	return xxx_messageInfo_DiskIDs.Size(m)
-}
-func (m *DiskIDs) XXX_DiscardUnknown() {
-	xxx_messageInfo_DiskIDs.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_DiskIDs proto.InternalMessageInfo
-
-func (m *DiskIDs) GetIdentifiers() map[string]string {
-	if m != nil {
-		return m.Identifiers
-	}
-	return nil
-}
-
-type ListDiskIDsResponse struct {
-	// Map of disk device numbers and IDs <page83> associated with each disk device
-	DiskIDs              map[string]*DiskIDs `protobuf:"bytes,1,rep,name=diskIDs,proto3" json:"diskIDs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
-	XXX_unrecognized     []byte              `json:"-"`
-	XXX_sizecache        int32               `json:"-"`
-}
-
-func (m *ListDiskIDsResponse) Reset()         { *m = ListDiskIDsResponse{} }
-func (m *ListDiskIDsResponse) String() string { return proto.CompactTextString(m) }
-func (*ListDiskIDsResponse) ProtoMessage()    {}
-func (*ListDiskIDsResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{9}
-}
-
-func (m *ListDiskIDsResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ListDiskIDsResponse.Unmarshal(m, b)
-}
-func (m *ListDiskIDsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ListDiskIDsResponse.Marshal(b, m, deterministic)
-}
-func (m *ListDiskIDsResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ListDiskIDsResponse.Merge(m, src)
-}
-func (m *ListDiskIDsResponse) XXX_Size() int {
-	return xxx_messageInfo_ListDiskIDsResponse.Size(m)
-}
-func (m *ListDiskIDsResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_ListDiskIDsResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ListDiskIDsResponse proto.InternalMessageInfo
-
-func (m *ListDiskIDsResponse) GetDiskIDs() map[string]*DiskIDs {
-	if m != nil {
-		return m.DiskIDs
-	}
-	return nil
-}
-
-type DiskStatsRequest struct {
-	// Disk device ID of the disk to get the size from
-	DiskID               string   `protobuf:"bytes,1,opt,name=diskID,proto3" json:"diskID,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *DiskStatsRequest) Reset()         { *m = DiskStatsRequest{} }
-func (m *DiskStatsRequest) String() string { return proto.CompactTextString(m) }
-func (*DiskStatsRequest) ProtoMessage()    {}
-func (*DiskStatsRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{10}
-}
-
-func (m *DiskStatsRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_DiskStatsRequest.Unmarshal(m, b)
-}
-func (m *DiskStatsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_DiskStatsRequest.Marshal(b, m, deterministic)
-}
-func (m *DiskStatsRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_DiskStatsRequest.Merge(m, src)
-}
-func (m *DiskStatsRequest) XXX_Size() int {
-	return xxx_messageInfo_DiskStatsRequest.Size(m)
-}
-func (m *DiskStatsRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_DiskStatsRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_DiskStatsRequest proto.InternalMessageInfo
-
-func (m *DiskStatsRequest) GetDiskID() string {
-	if m != nil {
-		return m.DiskID
-	}
-	return ""
-}
-
-type DiskStatsResponse struct {
-	//Total size of the volume
-	DiskSize             int64    `protobuf:"varint,1,opt,name=diskSize,proto3" json:"diskSize,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *DiskStatsResponse) Reset()         { *m = DiskStatsResponse{} }
-func (m *DiskStatsResponse) String() string { return proto.CompactTextString(m) }
-func (*DiskStatsResponse) ProtoMessage()    {}
-func (*DiskStatsResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_edb7884fca4087ac, []int{11}
-}
-
-func (m *DiskStatsResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_DiskStatsResponse.Unmarshal(m, b)
-}
-func (m *DiskStatsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_DiskStatsResponse.Marshal(b, m, deterministic)
-}
-func (m *DiskStatsResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_DiskStatsResponse.Merge(m, src)
-}
-func (m *DiskStatsResponse) XXX_Size() int {
-	return xxx_messageInfo_DiskStatsResponse.Size(m)
-}
-func (m *DiskStatsResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_DiskStatsResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_DiskStatsResponse proto.InternalMessageInfo
-
-func (m *DiskStatsResponse) GetDiskSize() int64 {
-	if m != nil {
-		return m.DiskSize
-	}
-	return 0
-}
-
-func init() {
-	proto.RegisterType((*ListDiskLocationsRequest)(nil), "v1beta1.ListDiskLocationsRequest")
-	proto.RegisterType((*DiskLocation)(nil), "v1beta1.DiskLocation")
-	proto.RegisterType((*ListDiskLocationsResponse)(nil), "v1beta1.ListDiskLocationsResponse")
-	proto.RegisterMapType((map[string]*DiskLocation)(nil), "v1beta1.ListDiskLocationsResponse.DiskLocationsEntry")
-	proto.RegisterType((*PartitionDiskRequest)(nil), "v1beta1.PartitionDiskRequest")
-	proto.RegisterType((*PartitionDiskResponse)(nil), "v1beta1.PartitionDiskResponse")
-	proto.RegisterType((*RescanRequest)(nil), "v1beta1.RescanRequest")
-	proto.RegisterType((*RescanResponse)(nil), "v1beta1.RescanResponse")
-	proto.RegisterType((*ListDiskIDsRequest)(nil), "v1beta1.ListDiskIDsRequest")
-	proto.RegisterType((*DiskIDs)(nil), "v1beta1.DiskIDs")
-	proto.RegisterMapType((map[string]string)(nil), "v1beta1.DiskIDs.IdentifiersEntry")
-	proto.RegisterType((*ListDiskIDsResponse)(nil), "v1beta1.ListDiskIDsResponse")
-	proto.RegisterMapType((map[string]*DiskIDs)(nil), "v1beta1.ListDiskIDsResponse.DiskIDsEntry")
-	proto.RegisterType((*DiskStatsRequest)(nil), "v1beta1.DiskStatsRequest")
-	proto.RegisterType((*DiskStatsResponse)(nil), "v1beta1.DiskStatsResponse")
-}
-
-func init() { proto.RegisterFile("disk/v1beta1/api.proto", fileDescriptor_edb7884fca4087ac) }
-
-var fileDescriptor_edb7884fca4087ac = []byte{
-	// 564 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0x5d, 0x6f, 0xd3, 0x30,
-	0x14, 0x5d, 0xd6, 0x6d, 0xa5, 0xb7, 0x74, 0x74, 0xa6, 0xeb, 0x32, 0xf3, 0xa1, 0x2d, 0x0f, 0x68,
-	0x80, 0x96, 0x68, 0x45, 0x48, 0x88, 0x09, 0x24, 0xb6, 0xf0, 0x10, 0x54, 0xa1, 0x29, 0x03, 0x21,
-	0xa1, 0x49, 0x28, 0x4d, 0xcd, 0x66, 0xb5, 0x24, 0x21, 0x76, 0x26, 0xca, 0x3b, 0xaf, 0xfc, 0x0e,
-	0x7e, 0x0f, 0xbf, 0x08, 0x39, 0xb1, 0x83, 0xd3, 0x66, 0xdb, 0x5b, 0x7c, 0xee, 0xb9, 0xce, 0xbd,
-	0xe7, 0x1c, 0x19, 0xfa, 0x63, 0xca, 0x26, 0xce, 0xe5, 0xc1, 0x88, 0xf0, 0xe0, 0xc0, 0x09, 0x12,
-	0x6a, 0x27, 0x69, 0xcc, 0x63, 0xd4, 0x94, 0x90, 0x85, 0xc1, 0x1c, 0x52, 0xc6, 0x5d, 0xca, 0x26,
-	0xc3, 0x38, 0x0c, 0x38, 0x8d, 0x23, 0xe6, 0x93, 0xef, 0x19, 0x61, 0xdc, 0xba, 0x80, 0xdb, 0x3a,
-	0x8e, 0x4c, 0x68, 0xbe, 0x19, 0x07, 0x09, 0x27, 0xa9, 0x69, 0xec, 0x18, 0x7b, 0x2d, 0x5f, 0x1d,
-	0x51, 0x17, 0x1a, 0x47, 0x19, 0x33, 0x97, 0x73, 0x54, 0x7c, 0xa2, 0x3e, 0xac, 0x7d, 0x08, 0xd2,
-	0x73, 0xc2, 0xcd, 0x46, 0x0e, 0xca, 0x13, 0xea, 0xc1, 0xea, 0xf0, 0xe3, 0x7b, 0xcf, 0x35, 0x57,
-	0x72, 0xb8, 0x38, 0x58, 0x7f, 0x0d, 0xd8, 0xae, 0x19, 0x83, 0x25, 0x71, 0xc4, 0x08, 0x3a, 0x83,
-	0x75, 0xb1, 0xc6, 0x97, 0xa9, 0xaa, 0x98, 0xc6, 0x4e, 0x63, 0xaf, 0x3d, 0x78, 0x6e, 0xcb, 0x2d,
-	0xec, 0x2b, 0x7b, 0xed, 0x0a, 0xfa, 0x36, 0xe2, 0xe9, 0xcc, 0xef, 0x8c, 0x75, 0x0c, 0x7f, 0x02,
-	0xb4, 0x48, 0x12, 0x1b, 0x4d, 0xc8, 0x4c, 0xee, 0x29, 0x3e, 0xd1, 0x53, 0x58, 0xbd, 0x0c, 0xa6,
-	0x19, 0xc9, 0xb7, 0x6c, 0x0f, 0x36, 0xcb, 0x9f, 0xeb, 0xdd, 0x7e, 0xc1, 0x79, 0xb9, 0xfc, 0xc2,
-	0xb0, 0x6c, 0xe8, 0x9d, 0x04, 0x29, 0xa7, 0x02, 0x17, 0x1c, 0x29, 0xab, 0x90, 0x46, 0x4c, 0xe0,
-	0xb9, 0xf2, 0x76, 0x79, 0xb2, 0xb6, 0x60, 0x73, 0x8e, 0x5f, 0xec, 0x60, 0xdd, 0x81, 0x8e, 0x4f,
-	0x58, 0x18, 0x44, 0xca, 0x98, 0x2e, 0xac, 0x2b, 0x40, 0x52, 0x7a, 0x80, 0x94, 0x06, 0x9e, 0x5b,
-	0x1a, 0xf8, 0xdb, 0x80, 0xa6, 0x84, 0xd0, 0x31, 0xb4, 0xe9, 0x98, 0x44, 0x9c, 0x7e, 0xa5, 0x24,
-	0x55, 0x0a, 0xee, 0x56, 0x96, 0xf0, 0x5c, 0x66, 0x7b, 0xff, 0x39, 0x85, 0x5a, 0x7a, 0x17, 0x7e,
-	0x0d, 0xdd, 0x79, 0x42, 0x8d, 0x52, 0x3d, 0x5d, 0xa9, 0x96, 0x2e, 0xc9, 0x1f, 0x03, 0xee, 0x56,
-	0xe6, 0x94, 0x0e, 0x1f, 0x43, 0xb3, 0x10, 0x41, 0x0d, 0xf6, 0x78, 0xc1, 0x5a, 0x8d, 0xae, 0x86,
-	0x2d, 0x06, 0x54, 0x9d, 0x78, 0x58, 0xc4, 0x55, 0x15, 0x6a, 0x06, 0x7b, 0x54, 0xb5, 0xb0, 0x3b,
-	0xbf, 0xbd, 0x3e, 0xea, 0x13, 0xe8, 0x0a, 0xf4, 0x94, 0x07, 0x9c, 0xdd, 0xe4, 0x9c, 0x03, 0x1b,
-	0x1a, 0x57, 0xee, 0x84, 0xe1, 0x96, 0x28, 0x9f, 0xd2, 0x9f, 0x24, 0xa7, 0x37, 0xfc, 0xf2, 0x3c,
-	0xf8, 0xd5, 0x80, 0x15, 0xd1, 0x81, 0xce, 0x60, 0x63, 0x21, 0xbb, 0x68, 0xf7, 0xba, 0x5c, 0xe7,
-	0x93, 0x60, 0xeb, 0xe6, 0xe8, 0x5b, 0x4b, 0xe8, 0x04, 0x3a, 0x95, 0x44, 0xa1, 0x07, 0x65, 0x5b,
-	0x5d, 0x32, 0xf1, 0xc3, 0xab, 0xca, 0xe5, 0x8d, 0x87, 0xb0, 0x56, 0x24, 0x0f, 0xf5, 0x4b, 0x6e,
-	0x25, 0x9b, 0x78, 0x6b, 0x01, 0x2f, 0x9b, 0xdf, 0x41, 0x5b, 0x73, 0x13, 0xdd, 0xab, 0xf7, 0xb8,
-	0xb8, 0xe6, 0xfe, 0x75, 0x01, 0xb0, 0x96, 0x90, 0x0b, 0xad, 0x52, 0x72, 0xb4, 0x5d, 0x31, 0x52,
-	0xb7, 0x0c, 0xe3, 0xba, 0x92, 0xba, 0xe5, 0xe8, 0xd5, 0xe7, 0xc3, 0x73, 0xca, 0x2f, 0xb2, 0x91,
-	0x1d, 0xc6, 0xdf, 0x9c, 0x49, 0x36, 0x22, 0x69, 0x44, 0x38, 0x61, 0xfb, 0x21, 0xa3, 0x4e, 0xc8,
-	0xe8, 0x7e, 0x92, 0xc6, 0x3f, 0x66, 0x4e, 0x38, 0xa5, 0x24, 0xe2, 0xe2, 0xf9, 0x74, 0xf4, 0xf7,
-	0x74, 0xb4, 0x96, 0x3f, 0xa6, 0xcf, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0xd4, 0xb4, 0x44, 0xda,
-	0x66, 0x05, 0x00, 0x00,
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// DiskClient is the client API for Disk service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type DiskClient interface {
-	// ListDiskLocations returns locations <Adapter, Bus, Target, LUN ID> of all
-	// disk devices enumerated by the host
-	ListDiskLocations(ctx context.Context, in *ListDiskLocationsRequest, opts ...grpc.CallOption) (*ListDiskLocationsResponse, error)
-	// PartitionDisk initializes and partitions a disk device (if the disk has not
-	// been partitioned already) and returns the resulting volume device ID
-	PartitionDisk(ctx context.Context, in *PartitionDiskRequest, opts ...grpc.CallOption) (*PartitionDiskResponse, error)
-	// Rescan refreshes the host's storage cache
-	Rescan(ctx context.Context, in *RescanRequest, opts ...grpc.CallOption) (*RescanResponse, error)
-	// ListDiskIDs returns a map of DiskID objects where the key is the disk number
-	ListDiskIDs(ctx context.Context, in *ListDiskIDsRequest, opts ...grpc.CallOption) (*ListDiskIDsResponse, error)
-	DiskStats(ctx context.Context, in *DiskStatsRequest, opts ...grpc.CallOption) (*DiskStatsResponse, error)
-}
-
-type diskClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewDiskClient(cc *grpc.ClientConn) DiskClient {
-	return &diskClient{cc}
-}
-
-func (c *diskClient) ListDiskLocations(ctx context.Context, in *ListDiskLocationsRequest, opts ...grpc.CallOption) (*ListDiskLocationsResponse, error) {
-	out := new(ListDiskLocationsResponse)
-	err := c.cc.Invoke(ctx, "/v1beta1.Disk/ListDiskLocations", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *diskClient) PartitionDisk(ctx context.Context, in *PartitionDiskRequest, opts ...grpc.CallOption) (*PartitionDiskResponse, error) {
-	out := new(PartitionDiskResponse)
-	err := c.cc.Invoke(ctx, "/v1beta1.Disk/PartitionDisk", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *diskClient) Rescan(ctx context.Context, in *RescanRequest, opts ...grpc.CallOption) (*RescanResponse, error) {
-	out := new(RescanResponse)
-	err := c.cc.Invoke(ctx, "/v1beta1.Disk/Rescan", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *diskClient) ListDiskIDs(ctx context.Context, in *ListDiskIDsRequest, opts ...grpc.CallOption) (*ListDiskIDsResponse, error) {
-	out := new(ListDiskIDsResponse)
-	err := c.cc.Invoke(ctx, "/v1beta1.Disk/ListDiskIDs", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *diskClient) DiskStats(ctx context.Context, in *DiskStatsRequest, opts ...grpc.CallOption) (*DiskStatsResponse, error) {
-	out := new(DiskStatsResponse)
-	err := c.cc.Invoke(ctx, "/v1beta1.Disk/DiskStats", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// DiskServer is the server API for Disk service.
-type DiskServer interface {
-	// ListDiskLocations returns locations <Adapter, Bus, Target, LUN ID> of all
-	// disk devices enumerated by the host
-	ListDiskLocations(context.Context, *ListDiskLocationsRequest) (*ListDiskLocationsResponse, error)
-	// PartitionDisk initializes and partitions a disk device (if the disk has not
-	// been partitioned already) and returns the resulting volume device ID
-	PartitionDisk(context.Context, *PartitionDiskRequest) (*PartitionDiskResponse, error)
-	// Rescan refreshes the host's storage cache
-	Rescan(context.Context, *RescanRequest) (*RescanResponse, error)
-	// ListDiskIDs returns a map of DiskID objects where the key is the disk number
-	ListDiskIDs(context.Context, *ListDiskIDsRequest) (*ListDiskIDsResponse, error)
-	DiskStats(context.Context, *DiskStatsRequest) (*DiskStatsResponse, error)
-}
-
-// UnimplementedDiskServer can be embedded to have forward compatible implementations.
-type UnimplementedDiskServer struct {
-}
-
-func (*UnimplementedDiskServer) ListDiskLocations(ctx context.Context, req *ListDiskLocationsRequest) (*ListDiskLocationsResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method ListDiskLocations not implemented")
-}
-func (*UnimplementedDiskServer) PartitionDisk(ctx context.Context, req *PartitionDiskRequest) (*PartitionDiskResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method PartitionDisk not implemented")
-}
-func (*UnimplementedDiskServer) Rescan(ctx context.Context, req *RescanRequest) (*RescanResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method Rescan not implemented")
-}
-func (*UnimplementedDiskServer) ListDiskIDs(ctx context.Context, req *ListDiskIDsRequest) (*ListDiskIDsResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method ListDiskIDs not implemented")
-}
-func (*UnimplementedDiskServer) DiskStats(ctx context.Context, req *DiskStatsRequest) (*DiskStatsResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method DiskStats not implemented")
-}
-
-func RegisterDiskServer(s *grpc.Server, srv DiskServer) {
-	s.RegisterService(&_Disk_serviceDesc, srv)
-}
-
-func _Disk_ListDiskLocations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ListDiskLocationsRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(DiskServer).ListDiskLocations(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v1beta1.Disk/ListDiskLocations",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(DiskServer).ListDiskLocations(ctx, req.(*ListDiskLocationsRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Disk_PartitionDisk_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(PartitionDiskRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(DiskServer).PartitionDisk(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v1beta1.Disk/PartitionDisk",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(DiskServer).PartitionDisk(ctx, req.(*PartitionDiskRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Disk_Rescan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(RescanRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(DiskServer).Rescan(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v1beta1.Disk/Rescan",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(DiskServer).Rescan(ctx, req.(*RescanRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Disk_ListDiskIDs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ListDiskIDsRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(DiskServer).ListDiskIDs(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v1beta1.Disk/ListDiskIDs",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(DiskServer).ListDiskIDs(ctx, req.(*ListDiskIDsRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Disk_DiskStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(DiskStatsRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(DiskServer).DiskStats(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v1beta1.Disk/DiskStats",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(DiskServer).DiskStats(ctx, req.(*DiskStatsRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Disk_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "v1beta1.Disk",
-	HandlerType: (*DiskServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "ListDiskLocations",
-			Handler:    _Disk_ListDiskLocations_Handler,
-		},
-		{
-			MethodName: "PartitionDisk",
-			Handler:    _Disk_PartitionDisk_Handler,
-		},
-		{
-			MethodName: "Rescan",
-			Handler:    _Disk_Rescan_Handler,
-		},
-		{
-			MethodName: "ListDiskIDs",
-			Handler:    _Disk_ListDiskIDs_Handler,
-		},
-		{
-			MethodName: "DiskStats",
-			Handler:    _Disk_DiskStats_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "disk/v1beta1/api.proto",
-}
diff --git a/vendor/github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1/api.proto b/vendor/github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1/api.proto
deleted file mode 100644
index 4673b2cf..00000000
--- a/vendor/github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1/api.proto
+++ /dev/null
@@ -1,81 +0,0 @@
-syntax = "proto3";
-
-package v1beta1;
-
-option go_package = "github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1";
-
-service Disk {
-    // ListDiskLocations returns locations <Adapter, Bus, Target, LUN ID> of all
-    // disk devices enumerated by the host
-    rpc ListDiskLocations(ListDiskLocationsRequest) returns (ListDiskLocationsResponse) {}
-
-    // PartitionDisk initializes and partitions a disk device (if the disk has not
-    // been partitioned already) and returns the resulting volume device ID
-    rpc PartitionDisk(PartitionDiskRequest) returns (PartitionDiskResponse) {}
-
-    // Rescan refreshes the host's storage cache
-    rpc Rescan(RescanRequest) returns (RescanResponse) {}
-
-    // ListDiskIDs returns a map of DiskID objects where the key is the disk number
-    rpc ListDiskIDs(ListDiskIDsRequest) returns (ListDiskIDsResponse) {}
-
-    // DiskStats returns the stats for the disk
-    rpc DiskStats(DiskStatsRequest) returns (DiskStatsResponse) {}
-}
-
-message ListDiskLocationsRequest {
-    // Intentionally empty
-}
-
-message DiskLocation {
-    string Adapter = 1;
-    string Bus = 2;
-    string Target = 3;
-    string LUNID = 4;
-}
-
-message ListDiskLocationsResponse {
-    // Map of disk device IDs and <adapter, bus, target, lun ID> associated with each disk device
-    map <string, DiskLocation> disk_locations = 1;
-}
-
-message PartitionDiskRequest {
-    // Disk device ID of the disk to partition
-    string diskID = 1;
-}
-
-message PartitionDiskResponse {
-    // Intentionally empty
-}
-
-message RescanRequest {
-    // Intentionally empty
-}
-
-message RescanResponse {
-    // Intentionally empty
-}
-
-message ListDiskIDsRequest {
-    // Intentionally empty
-}
-
-message DiskIDs {
-    // Map of Disk ID types and Disk ID values
-    map <string, string> identifiers = 1;
-}
-
-message ListDiskIDsResponse {
-    // Map of disk device numbers and IDs <page83> associated with each disk device
-    map <string, DiskIDs> diskIDs = 1;
-}
-
-message DiskStatsRequest {
-    // Disk device ID of the disk to get the size from
-    string diskID = 1;
-}
-
-message DiskStatsResponse {
-    //Total size of the volume
-    int64 diskSize = 1;
-}
diff --git a/vendor/github.com/kubernetes-csi/csi-proxy/client/groups/disk/v1beta1/client_generated.go b/vendor/github.com/kubernetes-csi/csi-proxy/client/groups/disk/v1beta1/client_generated.go
deleted file mode 100644
index 3ecd7c3b..00000000
--- a/vendor/github.com/kubernetes-csi/csi-proxy/client/groups/disk/v1beta1/client_generated.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Code generated by csi-proxy-api-gen. DO NOT EDIT.
-
-package v1beta1
-
-import (
-	"context"
-	"net"
-
-	"github.com/Microsoft/go-winio"
-	"github.com/kubernetes-csi/csi-proxy/client"
-	"github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1"
-	"github.com/kubernetes-csi/csi-proxy/client/apiversion"
-	"google.golang.org/grpc"
-)
-
-const groupName = "disk"
-
-var version = apiversion.NewVersionOrPanic("v1beta1")
-
-type Client struct {
-	client     v1beta1.DiskClient
-	connection *grpc.ClientConn
-}
-
-// NewClient returns a client to make calls to the disk API group version v1beta1.
-// It's the caller's responsibility to Close the client when done.
-func NewClient() (*Client, error) {
-	pipePath := client.PipePath(groupName, version)
-
-	connection, err := grpc.Dial(pipePath,
-		grpc.WithContextDialer(func(context context.Context, s string) (net.Conn, error) {
-			return winio.DialPipeContext(context, s)
-		}),
-		grpc.WithInsecure())
-	if err != nil {
-		return nil, err
-	}
-
-	client := v1beta1.NewDiskClient(connection)
-	return &Client{
-		client:     client,
-		connection: connection,
-	}, nil
-}
-
-// Close closes the client. It must be called before the client gets GC-ed.
-func (w *Client) Close() error {
-	return w.connection.Close()
-}
-
-// ensures we implement all the required methods
-var _ v1beta1.DiskClient = &Client{}
-
-func (w *Client) DiskStats(context context.Context, request *v1beta1.DiskStatsRequest, opts ...grpc.CallOption) (*v1beta1.DiskStatsResponse, error) {
-	return w.client.DiskStats(context, request, opts...)
-}
-
-func (w *Client) ListDiskIDs(context context.Context, request *v1beta1.ListDiskIDsRequest, opts ...grpc.CallOption) (*v1beta1.ListDiskIDsResponse, error) {
-	return w.client.ListDiskIDs(context, request, opts...)
-}
-
-func (w *Client) ListDiskLocations(context context.Context, request *v1beta1.ListDiskLocationsRequest, opts ...grpc.CallOption) (*v1beta1.ListDiskLocationsResponse, error) {
-	return w.client.ListDiskLocations(context, request, opts...)
-}
-
-func (w *Client) PartitionDisk(context context.Context, request *v1beta1.PartitionDiskRequest, opts ...grpc.CallOption) (*v1beta1.PartitionDiskResponse, error) {
-	return w.client.PartitionDisk(context, request, opts...)
-}
-
-func (w *Client) Rescan(context context.Context, request *v1beta1.RescanRequest, opts ...grpc.CallOption) (*v1beta1.RescanResponse, error) {
-	return w.client.Rescan(context, request, opts...)
-}
diff --git a/vendor/k8s.io/component-base/LICENSE b/vendor/k8s.io/component-base/LICENSE
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/vendor/k8s.io/component-base/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/vendor/k8s.io/component-base/cli/flag/ciphersuites_flag.go b/vendor/k8s.io/component-base/cli/flag/ciphersuites_flag.go
new file mode 100644
index 00000000..4fecd173
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/ciphersuites_flag.go
@@ -0,0 +1,106 @@
+/*
+Copyright 2017 The Kubernetes 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 flag
+
+import (
+	"crypto/tls"
+	"fmt"
+
+	"k8s.io/apimachinery/pkg/util/sets"
+)
+
+// ciphers maps strings into tls package cipher constants in
+// https://golang.org/pkg/crypto/tls/#pkg-constants
+var ciphers = map[string]uint16{
+	"TLS_RSA_WITH_RC4_128_SHA":                tls.TLS_RSA_WITH_RC4_128_SHA,
+	"TLS_RSA_WITH_3DES_EDE_CBC_SHA":           tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+	"TLS_RSA_WITH_AES_128_CBC_SHA":            tls.TLS_RSA_WITH_AES_128_CBC_SHA,
+	"TLS_RSA_WITH_AES_256_CBC_SHA":            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
+	"TLS_RSA_WITH_AES_128_CBC_SHA256":         tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
+	"TLS_RSA_WITH_AES_128_GCM_SHA256":         tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
+	"TLS_RSA_WITH_AES_256_GCM_SHA384":         tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
+	"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA":        tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+	"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+	"TLS_ECDHE_RSA_WITH_RC4_128_SHA":          tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+	"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA":     tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+	"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+	"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+	"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+	"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384":   tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+	"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+	"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305":    tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+	"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305":  tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+}
+
+func TLSCipherPossibleValues() []string {
+	cipherKeys := sets.NewString()
+	for key := range ciphers {
+		cipherKeys.Insert(key)
+	}
+	return cipherKeys.List()
+}
+
+func TLSCipherSuites(cipherNames []string) ([]uint16, error) {
+	if len(cipherNames) == 0 {
+		return nil, nil
+	}
+	ciphersIntSlice := make([]uint16, 0)
+	for _, cipher := range cipherNames {
+		intValue, ok := ciphers[cipher]
+		if !ok {
+			return nil, fmt.Errorf("Cipher suite %s not supported or doesn't exist", cipher)
+		}
+		ciphersIntSlice = append(ciphersIntSlice, intValue)
+	}
+	return ciphersIntSlice, nil
+}
+
+var versions = map[string]uint16{
+	"VersionTLS10": tls.VersionTLS10,
+	"VersionTLS11": tls.VersionTLS11,
+	"VersionTLS12": tls.VersionTLS12,
+	"VersionTLS13": tls.VersionTLS13,
+}
+
+func TLSPossibleVersions() []string {
+	versionsKeys := sets.NewString()
+	for key := range versions {
+		versionsKeys.Insert(key)
+	}
+	return versionsKeys.List()
+}
+
+func TLSVersion(versionName string) (uint16, error) {
+	if len(versionName) == 0 {
+		return DefaultTLSVersion(), nil
+	}
+	if version, ok := versions[versionName]; ok {
+		return version, nil
+	}
+	return 0, fmt.Errorf("unknown tls version %q", versionName)
+}
+
+func DefaultTLSVersion() uint16 {
+	// Can't use SSLv3 because of POODLE and BEAST
+	// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
+	// Can't use TLSv1.1 because of RC4 cipher usage
+	return tls.VersionTLS12
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/colon_separated_multimap_string_string.go b/vendor/k8s.io/component-base/cli/flag/colon_separated_multimap_string_string.go
new file mode 100644
index 00000000..bd2cf5f8
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/colon_separated_multimap_string_string.go
@@ -0,0 +1,102 @@
+/*
+Copyright 2017 The Kubernetes 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 flag
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+// ColonSeparatedMultimapStringString supports setting a map[string][]string from an encoding
+// that separates keys from values with ':' and separates key-value pairs with ','.
+// A key can be repeated multiple times, in which case the values are appended to a
+// slice of strings associated with that key. Items in the list associated with a given
+// key will appear in the order provided.
+// For example: `a:hello,b:again,c:world,b:beautiful` results in `{"a": ["hello"], "b": ["again", "beautiful"], "c": ["world"]}`
+// The first call to Set will clear the map before adding entries; subsequent calls will simply append to the map.
+// This makes it possible to override default values with a command-line option rather than appending to defaults,
+// while still allowing the distribution of key-value pairs across multiple flag invocations.
+// For example: `--flag "a:hello" --flag "b:again" --flag "b:beautiful" --flag "c:world"` results in `{"a": ["hello"], "b": ["again", "beautiful"], "c": ["world"]}`
+type ColonSeparatedMultimapStringString struct {
+	Multimap    *map[string][]string
+	initialized bool // set to true after the first Set call
+}
+
+// NewColonSeparatedMultimapStringString takes a pointer to a map[string][]string and returns the
+// ColonSeparatedMultimapStringString flag parsing shim for that map.
+func NewColonSeparatedMultimapStringString(m *map[string][]string) *ColonSeparatedMultimapStringString {
+	return &ColonSeparatedMultimapStringString{Multimap: m}
+}
+
+// Set implements github.com/spf13/pflag.Value
+func (m *ColonSeparatedMultimapStringString) Set(value string) error {
+	if m.Multimap == nil {
+		return fmt.Errorf("no target (nil pointer to map[string][]string)")
+	}
+	if !m.initialized || *m.Multimap == nil {
+		// clear default values, or allocate if no existing map
+		*m.Multimap = make(map[string][]string)
+		m.initialized = true
+	}
+	for _, pair := range strings.Split(value, ",") {
+		if len(pair) == 0 {
+			continue
+		}
+		kv := strings.SplitN(pair, ":", 2)
+		if len(kv) != 2 {
+			return fmt.Errorf("malformed pair, expect string:string")
+		}
+		k := strings.TrimSpace(kv[0])
+		v := strings.TrimSpace(kv[1])
+		(*m.Multimap)[k] = append((*m.Multimap)[k], v)
+	}
+	return nil
+}
+
+// String implements github.com/spf13/pflag.Value
+func (m *ColonSeparatedMultimapStringString) String() string {
+	type kv struct {
+		k string
+		v string
+	}
+	kvs := make([]kv, 0, len(*m.Multimap))
+	for k, vs := range *m.Multimap {
+		for i := range vs {
+			kvs = append(kvs, kv{k: k, v: vs[i]})
+		}
+	}
+	// stable sort by keys, order of values should be preserved
+	sort.SliceStable(kvs, func(i, j int) bool {
+		return kvs[i].k < kvs[j].k
+	})
+	pairs := make([]string, 0, len(kvs))
+	for i := range kvs {
+		pairs = append(pairs, fmt.Sprintf("%s:%s", kvs[i].k, kvs[i].v))
+	}
+	return strings.Join(pairs, ",")
+}
+
+// Type implements github.com/spf13/pflag.Value
+func (m *ColonSeparatedMultimapStringString) Type() string {
+	return "colonSeparatedMultimapStringString"
+}
+
+// Empty implements OmitEmpty
+func (m *ColonSeparatedMultimapStringString) Empty() bool {
+	return len(*m.Multimap) == 0
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/configuration_map.go b/vendor/k8s.io/component-base/cli/flag/configuration_map.go
new file mode 100644
index 00000000..911b05ec
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/configuration_map.go
@@ -0,0 +1,53 @@
+/*
+Copyright 2014 The Kubernetes 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 flag
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+type ConfigurationMap map[string]string
+
+func (m *ConfigurationMap) String() string {
+	pairs := []string{}
+	for k, v := range *m {
+		pairs = append(pairs, fmt.Sprintf("%s=%s", k, v))
+	}
+	sort.Strings(pairs)
+	return strings.Join(pairs, ",")
+}
+
+func (m *ConfigurationMap) Set(value string) error {
+	for _, s := range strings.Split(value, ",") {
+		if len(s) == 0 {
+			continue
+		}
+		arr := strings.SplitN(s, "=", 2)
+		if len(arr) == 2 {
+			(*m)[strings.TrimSpace(arr[0])] = strings.TrimSpace(arr[1])
+		} else {
+			(*m)[strings.TrimSpace(arr[0])] = ""
+		}
+	}
+	return nil
+}
+
+func (*ConfigurationMap) Type() string {
+	return "mapStringString"
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/flags.go b/vendor/k8s.io/component-base/cli/flag/flags.go
new file mode 100644
index 00000000..d0fff8db
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/flags.go
@@ -0,0 +1,54 @@
+/*
+Copyright 2014 The Kubernetes 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 flag
+
+import (
+	goflag "flag"
+	"strings"
+
+	"github.com/spf13/pflag"
+	"k8s.io/klog"
+)
+
+// WordSepNormalizeFunc changes all flags that contain "_" separators
+func WordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
+	if strings.Contains(name, "_") {
+		return pflag.NormalizedName(strings.Replace(name, "_", "-", -1))
+	}
+	return pflag.NormalizedName(name)
+}
+
+// WarnWordSepNormalizeFunc changes and warns for flags that contain "_" separators
+func WarnWordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
+	if strings.Contains(name, "_") {
+		nname := strings.Replace(name, "_", "-", -1)
+		klog.Warningf("%s is DEPRECATED and will be removed in a future version. Use %s instead.", name, nname)
+
+		return pflag.NormalizedName(nname)
+	}
+	return pflag.NormalizedName(name)
+}
+
+// InitFlags normalizes, parses, then logs the command line flags
+func InitFlags() {
+	pflag.CommandLine.SetNormalizeFunc(WordSepNormalizeFunc)
+	pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
+	pflag.Parse()
+	pflag.VisitAll(func(flag *pflag.Flag) {
+		klog.V(2).Infof("FLAG: --%s=%q", flag.Name, flag.Value)
+	})
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/langle_separated_map_string_string.go b/vendor/k8s.io/component-base/cli/flag/langle_separated_map_string_string.go
new file mode 100644
index 00000000..bf8dbfb9
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/langle_separated_map_string_string.go
@@ -0,0 +1,82 @@
+/*
+Copyright 2017 The Kubernetes 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 flag
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+// LangleSeparatedMapStringString can be set from the command line with the format `--flag "string<string"`.
+// Multiple comma-separated key-value pairs in a single invocation are supported. For example: `--flag "a<foo,b<bar"`.
+// Multiple flag invocations are supported. For example: `--flag "a<foo" --flag "b<foo"`.
+type LangleSeparatedMapStringString struct {
+	Map         *map[string]string
+	initialized bool // set to true after first Set call
+}
+
+// NewLangleSeparatedMapStringString takes a pointer to a map[string]string and returns the
+// LangleSeparatedMapStringString flag parsing shim for that map
+func NewLangleSeparatedMapStringString(m *map[string]string) *LangleSeparatedMapStringString {
+	return &LangleSeparatedMapStringString{Map: m}
+}
+
+// String implements github.com/spf13/pflag.Value
+func (m *LangleSeparatedMapStringString) String() string {
+	pairs := []string{}
+	for k, v := range *m.Map {
+		pairs = append(pairs, fmt.Sprintf("%s<%s", k, v))
+	}
+	sort.Strings(pairs)
+	return strings.Join(pairs, ",")
+}
+
+// Set implements github.com/spf13/pflag.Value
+func (m *LangleSeparatedMapStringString) Set(value string) error {
+	if m.Map == nil {
+		return fmt.Errorf("no target (nil pointer to map[string]string)")
+	}
+	if !m.initialized || *m.Map == nil {
+		// clear default values, or allocate if no existing map
+		*m.Map = make(map[string]string)
+		m.initialized = true
+	}
+	for _, s := range strings.Split(value, ",") {
+		if len(s) == 0 {
+			continue
+		}
+		arr := strings.SplitN(s, "<", 2)
+		if len(arr) != 2 {
+			return fmt.Errorf("malformed pair, expect string<string")
+		}
+		k := strings.TrimSpace(arr[0])
+		v := strings.TrimSpace(arr[1])
+		(*m.Map)[k] = v
+	}
+	return nil
+}
+
+// Type implements github.com/spf13/pflag.Value
+func (*LangleSeparatedMapStringString) Type() string {
+	return "mapStringString"
+}
+
+// Empty implements OmitEmpty
+func (m *LangleSeparatedMapStringString) Empty() bool {
+	return len(*m.Map) == 0
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/map_string_bool.go b/vendor/k8s.io/component-base/cli/flag/map_string_bool.go
new file mode 100644
index 00000000..e5a01805
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/map_string_bool.go
@@ -0,0 +1,90 @@
+/*
+Copyright 2017 The Kubernetes 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 flag
+
+import (
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// MapStringBool can be set from the command line with the format `--flag "string=bool"`.
+// Multiple comma-separated key-value pairs in a single invocation are supported. For example: `--flag "a=true,b=false"`.
+// Multiple flag invocations are supported. For example: `--flag "a=true" --flag "b=false"`.
+type MapStringBool struct {
+	Map         *map[string]bool
+	initialized bool
+}
+
+// NewMapStringBool takes a pointer to a map[string]string and returns the
+// MapStringBool flag parsing shim for that map
+func NewMapStringBool(m *map[string]bool) *MapStringBool {
+	return &MapStringBool{Map: m}
+}
+
+// String implements github.com/spf13/pflag.Value
+func (m *MapStringBool) String() string {
+	if m == nil || m.Map == nil {
+		return ""
+	}
+	pairs := []string{}
+	for k, v := range *m.Map {
+		pairs = append(pairs, fmt.Sprintf("%s=%t", k, v))
+	}
+	sort.Strings(pairs)
+	return strings.Join(pairs, ",")
+}
+
+// Set implements github.com/spf13/pflag.Value
+func (m *MapStringBool) Set(value string) error {
+	if m.Map == nil {
+		return fmt.Errorf("no target (nil pointer to map[string]bool)")
+	}
+	if !m.initialized || *m.Map == nil {
+		// clear default values, or allocate if no existing map
+		*m.Map = make(map[string]bool)
+		m.initialized = true
+	}
+	for _, s := range strings.Split(value, ",") {
+		if len(s) == 0 {
+			continue
+		}
+		arr := strings.SplitN(s, "=", 2)
+		if len(arr) != 2 {
+			return fmt.Errorf("malformed pair, expect string=bool")
+		}
+		k := strings.TrimSpace(arr[0])
+		v := strings.TrimSpace(arr[1])
+		boolValue, err := strconv.ParseBool(v)
+		if err != nil {
+			return fmt.Errorf("invalid value of %s: %s, err: %v", k, v, err)
+		}
+		(*m.Map)[k] = boolValue
+	}
+	return nil
+}
+
+// Type implements github.com/spf13/pflag.Value
+func (*MapStringBool) Type() string {
+	return "mapStringBool"
+}
+
+// Empty implements OmitEmpty
+func (m *MapStringBool) Empty() bool {
+	return len(*m.Map) == 0
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/map_string_string.go b/vendor/k8s.io/component-base/cli/flag/map_string_string.go
new file mode 100644
index 00000000..129470b3
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/map_string_string.go
@@ -0,0 +1,112 @@
+/*
+Copyright 2017 The Kubernetes 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 flag
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+// MapStringString can be set from the command line with the format `--flag "string=string"`.
+// Multiple flag invocations are supported. For example: `--flag "a=foo" --flag "b=bar"`. If this is desired
+// to be the only type invocation `NoSplit` should be set to true.
+// Multiple comma-separated key-value pairs in a single invocation are supported if `NoSplit`
+// is set to false. For example: `--flag "a=foo,b=bar"`.
+type MapStringString struct {
+	Map         *map[string]string
+	initialized bool
+	NoSplit     bool
+}
+
+// NewMapStringString takes a pointer to a map[string]string and returns the
+// MapStringString flag parsing shim for that map
+func NewMapStringString(m *map[string]string) *MapStringString {
+	return &MapStringString{Map: m}
+}
+
+// NewMapStringString takes a pointer to a map[string]string and sets `NoSplit`
+// value to `true` and returns the MapStringString flag parsing shim for that map
+func NewMapStringStringNoSplit(m *map[string]string) *MapStringString {
+	return &MapStringString{
+		Map:     m,
+		NoSplit: true,
+	}
+}
+
+// String implements github.com/spf13/pflag.Value
+func (m *MapStringString) String() string {
+	if m == nil || m.Map == nil {
+		return ""
+	}
+	pairs := []string{}
+	for k, v := range *m.Map {
+		pairs = append(pairs, fmt.Sprintf("%s=%s", k, v))
+	}
+	sort.Strings(pairs)
+	return strings.Join(pairs, ",")
+}
+
+// Set implements github.com/spf13/pflag.Value
+func (m *MapStringString) Set(value string) error {
+	if m.Map == nil {
+		return fmt.Errorf("no target (nil pointer to map[string]string)")
+	}
+	if !m.initialized || *m.Map == nil {
+		// clear default values, or allocate if no existing map
+		*m.Map = make(map[string]string)
+		m.initialized = true
+	}
+
+	// account for comma-separated key-value pairs in a single invocation
+	if !m.NoSplit {
+		for _, s := range strings.Split(value, ",") {
+			if len(s) == 0 {
+				continue
+			}
+			arr := strings.SplitN(s, "=", 2)
+			if len(arr) != 2 {
+				return fmt.Errorf("malformed pair, expect string=string")
+			}
+			k := strings.TrimSpace(arr[0])
+			v := strings.TrimSpace(arr[1])
+			(*m.Map)[k] = v
+		}
+		return nil
+	}
+
+	// account for only one key-value pair in a single invocation
+	arr := strings.SplitN(value, "=", 2)
+	if len(arr) != 2 {
+		return fmt.Errorf("malformed pair, expect string=string")
+	}
+	k := strings.TrimSpace(arr[0])
+	v := strings.TrimSpace(arr[1])
+	(*m.Map)[k] = v
+	return nil
+
+}
+
+// Type implements github.com/spf13/pflag.Value
+func (*MapStringString) Type() string {
+	return "mapStringString"
+}
+
+// Empty implements OmitEmpty
+func (m *MapStringString) Empty() bool {
+	return len(*m.Map) == 0
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/namedcertkey_flag.go b/vendor/k8s.io/component-base/cli/flag/namedcertkey_flag.go
new file mode 100644
index 00000000..bc686774
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/namedcertkey_flag.go
@@ -0,0 +1,113 @@
+/*
+Copyright 2016 The Kubernetes 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 flag
+
+import (
+	"errors"
+	"flag"
+	"strings"
+)
+
+// NamedCertKey is a flag value parsing "certfile,keyfile" and "certfile,keyfile:name,name,name".
+type NamedCertKey struct {
+	Names             []string
+	CertFile, KeyFile string
+}
+
+var _ flag.Value = &NamedCertKey{}
+
+func (nkc *NamedCertKey) String() string {
+	s := nkc.CertFile + "," + nkc.KeyFile
+	if len(nkc.Names) > 0 {
+		s = s + ":" + strings.Join(nkc.Names, ",")
+	}
+	return s
+}
+
+func (nkc *NamedCertKey) Set(value string) error {
+	cs := strings.SplitN(value, ":", 2)
+	var keycert string
+	if len(cs) == 2 {
+		var names string
+		keycert, names = strings.TrimSpace(cs[0]), strings.TrimSpace(cs[1])
+		if names == "" {
+			return errors.New("empty names list is not allowed")
+		}
+		nkc.Names = nil
+		for _, name := range strings.Split(names, ",") {
+			nkc.Names = append(nkc.Names, strings.TrimSpace(name))
+		}
+	} else {
+		nkc.Names = nil
+		keycert = strings.TrimSpace(cs[0])
+	}
+	cs = strings.Split(keycert, ",")
+	if len(cs) != 2 {
+		return errors.New("expected comma separated certificate and key file paths")
+	}
+	nkc.CertFile = strings.TrimSpace(cs[0])
+	nkc.KeyFile = strings.TrimSpace(cs[1])
+	return nil
+}
+
+func (*NamedCertKey) Type() string {
+	return "namedCertKey"
+}
+
+// NamedCertKeyArray is a flag value parsing NamedCertKeys, each passed with its own
+// flag instance (in contrast to comma separated slices).
+type NamedCertKeyArray struct {
+	value   *[]NamedCertKey
+	changed bool
+}
+
+var _ flag.Value = &NamedCertKey{}
+
+// NewNamedKeyCertArray creates a new NamedCertKeyArray with the internal value
+// pointing to p.
+func NewNamedCertKeyArray(p *[]NamedCertKey) *NamedCertKeyArray {
+	return &NamedCertKeyArray{
+		value: p,
+	}
+}
+
+func (a *NamedCertKeyArray) Set(val string) error {
+	nkc := NamedCertKey{}
+	err := nkc.Set(val)
+	if err != nil {
+		return err
+	}
+	if !a.changed {
+		*a.value = []NamedCertKey{nkc}
+		a.changed = true
+	} else {
+		*a.value = append(*a.value, nkc)
+	}
+	return nil
+}
+
+func (a *NamedCertKeyArray) Type() string {
+	return "namedCertKey"
+}
+
+func (a *NamedCertKeyArray) String() string {
+	nkcs := make([]string, 0, len(*a.value))
+	for i := range *a.value {
+		nkcs = append(nkcs, (*a.value)[i].String())
+	}
+	return "[" + strings.Join(nkcs, ";") + "]"
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/noop.go b/vendor/k8s.io/component-base/cli/flag/noop.go
new file mode 100644
index 00000000..03f7f14c
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/noop.go
@@ -0,0 +1,41 @@
+/*
+Copyright 2018 The Kubernetes 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 flag
+
+import (
+	goflag "flag"
+	"github.com/spf13/pflag"
+)
+
+// NoOp implements goflag.Value and plfag.Value,
+// but has a noop Set implementation
+type NoOp struct{}
+
+var _ goflag.Value = NoOp{}
+var _ pflag.Value = NoOp{}
+
+func (NoOp) String() string {
+	return ""
+}
+
+func (NoOp) Set(val string) error {
+	return nil
+}
+
+func (NoOp) Type() string {
+	return "NoOp"
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/omitempty.go b/vendor/k8s.io/component-base/cli/flag/omitempty.go
new file mode 100644
index 00000000..c354754e
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/omitempty.go
@@ -0,0 +1,24 @@
+/*
+Copyright 2017 The Kubernetes 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 flag
+
+// OmitEmpty is an interface for flags to report whether their underlying value
+// is "empty." If a flag implements OmitEmpty and returns true for a call to Empty(),
+// it is assumed that flag may be omitted from the command line.
+type OmitEmpty interface {
+	Empty() bool
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/sectioned.go b/vendor/k8s.io/component-base/cli/flag/sectioned.go
new file mode 100644
index 00000000..493a6c0f
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/sectioned.go
@@ -0,0 +1,79 @@
+/*
+Copyright 2018 The Kubernetes 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 flag
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"strings"
+
+	"github.com/spf13/pflag"
+)
+
+// NamedFlagSets stores named flag sets in the order of calling FlagSet.
+type NamedFlagSets struct {
+	// Order is an ordered list of flag set names.
+	Order []string
+	// FlagSets stores the flag sets by name.
+	FlagSets map[string]*pflag.FlagSet
+}
+
+// FlagSet returns the flag set with the given name and adds it to the
+// ordered name list if it is not in there yet.
+func (nfs *NamedFlagSets) FlagSet(name string) *pflag.FlagSet {
+	if nfs.FlagSets == nil {
+		nfs.FlagSets = map[string]*pflag.FlagSet{}
+	}
+	if _, ok := nfs.FlagSets[name]; !ok {
+		nfs.FlagSets[name] = pflag.NewFlagSet(name, pflag.ExitOnError)
+		nfs.Order = append(nfs.Order, name)
+	}
+	return nfs.FlagSets[name]
+}
+
+// PrintSections prints the given names flag sets in sections, with the maximal given column number.
+// If cols is zero, lines are not wrapped.
+func PrintSections(w io.Writer, fss NamedFlagSets, cols int) {
+	for _, name := range fss.Order {
+		fs := fss.FlagSets[name]
+		if !fs.HasFlags() {
+			continue
+		}
+
+		wideFS := pflag.NewFlagSet("", pflag.ExitOnError)
+		wideFS.AddFlagSet(fs)
+
+		var zzz string
+		if cols > 24 {
+			zzz = strings.Repeat("z", cols-24)
+			wideFS.Int(zzz, 0, strings.Repeat("z", cols-24))
+		}
+
+		var buf bytes.Buffer
+		fmt.Fprintf(&buf, "\n%s flags:\n\n%s", strings.ToUpper(name[:1])+name[1:], wideFS.FlagUsagesWrapped(cols))
+
+		if cols > 24 {
+			i := strings.Index(buf.String(), zzz)
+			lines := strings.Split(buf.String()[:i], "\n")
+			fmt.Fprint(w, strings.Join(lines[:len(lines)-1], "\n"))
+			fmt.Fprintln(w)
+		} else {
+			fmt.Fprint(w, buf.String())
+		}
+	}
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/string_flag.go b/vendor/k8s.io/component-base/cli/flag/string_flag.go
new file mode 100644
index 00000000..331bdb66
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/string_flag.go
@@ -0,0 +1,56 @@
+/*
+Copyright 2014 The Kubernetes 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 flag
+
+// StringFlag is a string flag compatible with flags and pflags that keeps track of whether it had a value supplied or not.
+type StringFlag struct {
+	// If Set has been invoked this value is true
+	provided bool
+	// The exact value provided on the flag
+	value string
+}
+
+func NewStringFlag(defaultVal string) StringFlag {
+	return StringFlag{value: defaultVal}
+}
+
+func (f *StringFlag) Default(value string) {
+	f.value = value
+}
+
+func (f StringFlag) String() string {
+	return f.value
+}
+
+func (f StringFlag) Value() string {
+	return f.value
+}
+
+func (f *StringFlag) Set(value string) error {
+	f.value = value
+	f.provided = true
+
+	return nil
+}
+
+func (f StringFlag) Provided() bool {
+	return f.provided
+}
+
+func (f *StringFlag) Type() string {
+	return "string"
+}
diff --git a/vendor/k8s.io/component-base/cli/flag/tristate.go b/vendor/k8s.io/component-base/cli/flag/tristate.go
new file mode 100644
index 00000000..cf16376b
--- /dev/null
+++ b/vendor/k8s.io/component-base/cli/flag/tristate.go
@@ -0,0 +1,83 @@
+/*
+Copyright 2014 The Kubernetes 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 flag
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// Tristate is a flag compatible with flags and pflags that
+// keeps track of whether it had a value supplied or not.
+type Tristate int
+
+const (
+	Unset Tristate = iota // 0
+	True
+	False
+)
+
+func (f *Tristate) Default(value bool) {
+	*f = triFromBool(value)
+}
+
+func (f Tristate) String() string {
+	b := boolFromTri(f)
+	return fmt.Sprintf("%t", b)
+}
+
+func (f Tristate) Value() bool {
+	b := boolFromTri(f)
+	return b
+}
+
+func (f *Tristate) Set(value string) error {
+	boolVal, err := strconv.ParseBool(value)
+	if err != nil {
+		return err
+	}
+
+	*f = triFromBool(boolVal)
+	return nil
+}
+
+func (f Tristate) Provided() bool {
+	if f != Unset {
+		return true
+	}
+	return false
+}
+
+func (f *Tristate) Type() string {
+	return "tristate"
+}
+
+func boolFromTri(t Tristate) bool {
+	if t == True {
+		return true
+	} else {
+		return false
+	}
+}
+
+func triFromBool(b bool) Tristate {
+	if b {
+		return True
+	} else {
+		return False
+	}
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 844cb236..403f3bc0 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -58,17 +58,13 @@ github.com/json-iterator/go
 github.com/konsorten/go-windows-terminal-sequences
 # github.com/kubernetes-csi/csi-proxy/client v0.2.2
 github.com/kubernetes-csi/csi-proxy/client
-github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta1
 github.com/kubernetes-csi/csi-proxy/client/api/disk/v1beta2
 github.com/kubernetes-csi/csi-proxy/client/api/filesystem/v1beta1
 github.com/kubernetes-csi/csi-proxy/client/api/volume/v1beta1
-github.com/kubernetes-csi/csi-proxy/client/api/volume/v1beta2
 github.com/kubernetes-csi/csi-proxy/client/apiversion
-github.com/kubernetes-csi/csi-proxy/client/groups/disk/v1beta1
 github.com/kubernetes-csi/csi-proxy/client/groups/disk/v1beta2
 github.com/kubernetes-csi/csi-proxy/client/groups/filesystem/v1beta1
 github.com/kubernetes-csi/csi-proxy/client/groups/volume/v1beta1
-github.com/kubernetes-csi/csi-proxy/client/groups/volume/v1beta2
 # github.com/kubernetes-csi/csi-test/v3 v3.0.0
 github.com/kubernetes-csi/csi-test/v3/pkg/sanity
 github.com/kubernetes-csi/csi-test/v3/utils
@@ -466,6 +462,8 @@ k8s.io/client-go/util/homedir
 k8s.io/client-go/util/jsonpath
 k8s.io/client-go/util/keyutil
 k8s.io/client-go/util/workqueue
+# k8s.io/component-base v0.18.0 => k8s.io/component-base v0.18.0
+k8s.io/component-base/cli/flag
 # k8s.io/klog v1.0.0
 k8s.io/klog
 # k8s.io/kubernetes v1.18.0


Test patch:
diff --git a/pkg/common/parameters_test.go b/pkg/common/parameters_test.go
index e104be55..4692e7e1 100644
--- a/pkg/common/parameters_test.go
+++ b/pkg/common/parameters_test.go
@@ -25,79 +25,105 @@ func TestExtractAndDefaultParameters(t *testing.T) {
 	tests := []struct {
 		name         string
 		parameters   map[string]string
+		labels       map[string]string
 		expectParams DiskParameters
 		expectErr    bool
 	}{
 		{
 			name:       "defaults",
 			parameters: map[string]string{},
+			labels:     map[string]string{},
 			expectParams: DiskParameters{
 				DiskType:             "pd-standard",
 				ReplicationType:      "none",
 				DiskEncryptionKMSKey: "",
 				Tags:                 make(map[string]string),
+				Labels:               make(map[string]string),
 			},
 		},
 		{
 			name:       "specified empties",
 			parameters: map[string]string{ParameterKeyType: "", ParameterKeyReplicationType: "", ParameterKeyDiskEncryptionKmsKey: ""},
+			labels:     map[string]string{},
 			expectParams: DiskParameters{
 				DiskType:             "pd-standard",
 				ReplicationType:      "none",
 				DiskEncryptionKMSKey: "",
 				Tags:                 make(map[string]string),
+				Labels:               make(map[string]string),
 			},
 		},
 		{
 			name:       "random keys",
 			parameters: map[string]string{ParameterKeyType: "", "foo": "", ParameterKeyDiskEncryptionKmsKey: ""},
+			labels:     map[string]string{},
 			expectErr:  true,
 		},
 		{
 			name:       "real values",
 			parameters: map[string]string{ParameterKeyType: "pd-ssd", ParameterKeyReplicationType: "regional-pd", ParameterKeyDiskEncryptionKmsKey: "foo/key"},
+			labels:     map[string]string{},
 			expectParams: DiskParameters{
 				DiskType:             "pd-ssd",
 				ReplicationType:      "regional-pd",
 				DiskEncryptionKMSKey: "foo/key",
 				Tags:                 make(map[string]string),
+				Labels:               make(map[string]string),
 			},
 		},
 		{
 			name:       "real values, checking balanced pd",
 			parameters: map[string]string{ParameterKeyType: "pd-balanced", ParameterKeyReplicationType: "regional-pd", ParameterKeyDiskEncryptionKmsKey: "foo/key"},
+			labels:     map[string]string{},
 			expectParams: DiskParameters{
 				DiskType:             "pd-balanced",
 				ReplicationType:      "regional-pd",
 				DiskEncryptionKMSKey: "foo/key",
 				Tags:                 make(map[string]string),
+				Labels:               make(map[string]string),
 			},
 		},
 		{
 			name:       "partial spec",
 			parameters: map[string]string{ParameterKeyDiskEncryptionKmsKey: "foo/key"},
+			labels:     map[string]string{},
 			expectParams: DiskParameters{
 				DiskType:             "pd-standard",
 				ReplicationType:      "none",
 				DiskEncryptionKMSKey: "foo/key",
 				Tags:                 make(map[string]string),
+				Labels:               make(map[string]string),
 			},
 		},
 		{
 			name:       "tags",
 			parameters: map[string]string{ParameterKeyPVCName: "testPVCName", ParameterKeyPVCNamespace: "testPVCNamespace", ParameterKeyPVName: "testPVName"},
+			labels:     map[string]string{},
 			expectParams: DiskParameters{
 				DiskType:             "pd-standard",
 				ReplicationType:      "none",
 				DiskEncryptionKMSKey: "",
 				Tags:                 map[string]string{tagKeyCreatedForClaimName: "testPVCName", tagKeyCreatedForClaimNamespace: "testPVCNamespace", tagKeyCreatedForVolumeName: "testPVName", tagKeyCreatedBy: "testDriver"},
+				Labels:               make(map[string]string),
+			},
+		},
+		{
+			name:       "labels",
+			parameters: map[string]string{},
+			labels:     map[string]string{"label-1": "label-value-1", "label-2": "label-value-2"},
+			expectParams: DiskParameters{
+				DiskType:             "pd-standard",
+				ReplicationType:      "none",
+				DiskEncryptionKMSKey: "",
+				Tags:                 map[string]string{},
+				Labels:               map[string]string{"label-1": "label-value-1", "label-2": "label-value-2"},
 			},
 		},
 	}
 
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
-			p, err := ExtractAndDefaultParameters(tc.parameters, "testDriver")
+			p, err := ExtractAndDefaultParameters(tc.parameters, "testDriver", tc.labels)
 			if gotErr := err != nil; gotErr != tc.expectErr {
 				t.Fatalf("ExtractAndDefaultParameters(%+v) = %v; expectedErr: %v", tc.parameters, err, tc.expectErr)
 			}
diff --git a/pkg/gce-pd-csi-driver/gce-pd-driver_test.go b/pkg/gce-pd-csi-driver/gce-pd-driver_test.go
index bf0ca5a4..d645907e 100644
--- a/pkg/gce-pd-csi-driver/gce-pd-driver_test.go
+++ b/pkg/gce-pd-csi-driver/gce-pd-driver_test.go
@@ -44,7 +44,7 @@ func initGCEDriverWithCloudProvider(t *testing.T, cloudProvider gce.GCECompute)
 	vendorVersion := "test-vendor"
 	gceDriver := GetGCEDriver()
 	controllerServer := NewControllerServer(gceDriver, cloudProvider)
-	err := gceDriver.SetupGCEDriver(driver, vendorVersion, nil, controllerServer, nil)
+	err := gceDriver.SetupGCEDriver(driver, vendorVersion, nil, nil, controllerServer, nil)
 	if err != nil {
 		t.Fatalf("Failed to setup GCE Driver: %v", err)
 	}
diff --git a/pkg/gce-pd-csi-driver/identity_test.go b/pkg/gce-pd-csi-driver/identity_test.go
index cdc8a813..14f6b131 100644
--- a/pkg/gce-pd-csi-driver/identity_test.go
+++ b/pkg/gce-pd-csi-driver/identity_test.go
@@ -26,7 +26,7 @@ func TestGetPluginInfo(t *testing.T) {
 	vendorVersion := "test-vendor"
 	gceDriver := GetGCEDriver()
 	identityServer := NewIdentityServer(gceDriver)
-	err := gceDriver.SetupGCEDriver(driver, vendorVersion, identityServer, nil, nil)
+	err := gceDriver.SetupGCEDriver(driver, vendorVersion, nil, identityServer, nil, nil)
 	if err != nil {
 		t.Fatalf("Failed to setup GCE Driver: %v", err)
 	}
@@ -49,7 +49,7 @@ func TestGetPluginInfo(t *testing.T) {
 func TestGetPluginCapabilities(t *testing.T) {
 	gceDriver := GetGCEDriver()
 	identityServer := NewIdentityServer(gceDriver)
-	err := gceDriver.SetupGCEDriver(driver, "test-vendor", identityServer, nil, nil)
+	err := gceDriver.SetupGCEDriver(driver, "test-vendor", nil, identityServer, nil, nil)
 	if err != nil {
 		t.Fatalf("Failed to setup GCE Driver: %v", err)
 	}
@@ -82,7 +82,7 @@ func TestGetPluginCapabilities(t *testing.T) {
 func TestProbe(t *testing.T) {
 	gceDriver := GetGCEDriver()
 	identityServer := NewIdentityServer(gceDriver)
-	err := gceDriver.SetupGCEDriver(driver, "test-vendor", identityServer, nil, nil)
+	err := gceDriver.SetupGCEDriver(driver, "test-vendor", nil, identityServer, nil, nil)
 	if err != nil {
 		t.Fatalf("Failed to setup GCE Driver: %v", err)
 	}
diff --git a/pkg/gce-pd-csi-driver/node_test.go b/pkg/gce-pd-csi-driver/node_test.go
index 221ab04d..1a65d189 100644
--- a/pkg/gce-pd-csi-driver/node_test.go
+++ b/pkg/gce-pd-csi-driver/node_test.go
@@ -43,7 +43,7 @@ func getTestGCEDriverWithCustomMounter(t *testing.T, mounter *mount.SafeFormatAn
 func getCustomTestGCEDriver(t *testing.T, mounter *mount.SafeFormatAndMount, deviceUtils mountmanager.DeviceUtils, metaService metadataservice.MetadataService) *GCEDriver {
 	gceDriver := GetGCEDriver()
 	nodeServer := NewNodeServer(gceDriver, mounter, deviceUtils, metaService, mountmanager.NewFakeStatter(mounter))
-	err := gceDriver.SetupGCEDriver(driver, "test-vendor", nil, nil, nodeServer)
+	err := gceDriver.SetupGCEDriver(driver, "test-vendor", nil, nil, nil, nodeServer)
 	if err != nil {
 		t.Fatalf("Failed to setup GCE Driver: %v", err)
 	}
@@ -54,7 +54,7 @@ func getTestBlockingGCEDriver(t *testing.T, readyToExecute chan chan struct{}) *
 	gceDriver := GetGCEDriver()
 	mounter := mountmanager.NewFakeSafeBlockingMounter(readyToExecute)
 	nodeServer := NewNodeServer(gceDriver, mounter, mountmanager.NewFakeDeviceUtils(), metadataservice.NewFakeService(), mountmanager.NewFakeStatter(mounter))
-	err := gceDriver.SetupGCEDriver(driver, "test-vendor", nil, nil, nodeServer)
+	err := gceDriver.SetupGCEDriver(driver, "test-vendor", nil, nil, nil, nodeServer)
 	if err != nil {
 		t.Fatalf("Failed to setup GCE Driver: %v", err)
 	}
diff --git a/test/k8s-integration/prepull.yaml b/test/k8s-integration/prepull.yaml
index 4a16542a..cd823d2b 100644
--- a/test/k8s-integration/prepull.yaml
+++ b/test/k8s-integration/prepull.yaml
@@ -33,7 +33,7 @@ spec:
       # run ping in each container to keep it alive so that kubernetes does not
       # continually restart the containers while we're prepulling.
       containers:
-      - image: k8s.gcr.io/e2e-test-images/agnhost:2.26
+      - image: k8s.gcr.io/e2e-test-images/agnhost:2.21
         name: agnhost-212
         resources:
           requests:
diff --git a/test/run-k8s-windows-migration.sh b/test/run-k8s-windows-migration.sh
deleted file mode 100755
index 6ca0e48d..00000000
--- a/test/run-k8s-windows-migration.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-# Optional environment variables
-# GCE_PD_OVERLAY_NAME: which Kustomize overlay to deploy with
-# GCE_PD_DO_DRIVER_BUILD: if set, don't build the driver from source and just
-#   use the driver version from the overlay
-# GCE_PD_BOSKOS_RESOURCE_TYPE: name of the boskos resource type to reserve
-
-set -o nounset
-set -o errexit
-
-export GCE_PD_VERBOSITY=9
-
-readonly PKGDIR=${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
-
-readonly overlay_name="${GCE_PD_OVERLAY_NAME:-stable}"
-readonly boskos_resource_type="${GCE_PD_BOSKOS_RESOURCE_TYPE:-gce-project}"
-readonly do_driver_build="${GCE_PD_DO_DRIVER_BUILD:-true}"
-readonly deployment_strategy=${DEPLOYMENT_STRATEGY:-gce}
-readonly kube_version=${GCE_PD_KUBE_VERSION:-master}
-readonly test_version=${TEST_VERSION:-master}
-
-readonly GCE_PD_TEST_FOCUS="PersistentVolumes\sGCEPD|[V|v]olume\sexpand|\[sig-storage\]\sIn-tree\sVolumes\s\[Driver:\swindows-gcepd\]|allowedTopologies|Pod\sDisks|PersistentVolumes\sDefault"
-
-# TODO(#167): Enable reconstructions tests
-
-make -C "${PKGDIR}" test-k8s-integration
-
-base_cmd="${PKGDIR}/bin/k8s-integration-test \
-        --platform=windows --bringup-cluster=false  --teardown-cluster=false \
-        --run-in-prow=true
-        --kube-feature-gates="CSIMigration=true,CSIMigrationGCE=true,ExpandCSIVolumes=true" --run-in-prow=true \
-        --deploy-overlay-name="${overlay_name}" --service-account-file="${E2E_GOOGLE_APPLICATION_CREDENTIALS}" \
-        --do-driver-build="${do_driver_build}" --boskos-resource-type="${boskos_resource_type}" \
-        --migration-test=true --test-focus="${GCE_PD_TEST_FOCUS}" \
-        --gce-zone="us-central1-b" --deployment-strategy="${deployment_strategy}" --test-version="${test_version}" "
-
-eval "$base_cmd"
-
diff --git a/test/run-windows-k8s-integration.sh b/test/run-windows-k8s-integration.sh
index a8120977..4c56c499 100755
--- a/test/run-windows-k8s-integration.sh
+++ b/test/run-windows-k8s-integration.sh
@@ -10,7 +10,7 @@ set -o nounset
 set -o errexit
 
 readonly PKGDIR=${GOPATH}/src/sigs.k8s.io/gcp-compute-persistent-disk-csi-driver
-readonly overlay_name="${GCE_PD_OVERLAY_NAME:-stable}"
+readonly overlay_name="${GCE_PD_OVERLAY_NAME:-alpha}"
 readonly do_driver_build="${GCE_PD_DO_DRIVER_BUILD:-true}"
 readonly deployment_strategy=${DEPLOYMENT_STRATEGY:-gce}
 readonly test_version=${TEST_VERSION:-master}
diff --git a/test/sanity/sanity_test.go b/test/sanity/sanity_test.go
index a5d09a35..45e94e30 100644
--- a/test/sanity/sanity_test.go
+++ b/test/sanity/sanity_test.go
@@ -39,6 +39,7 @@ func TestSanity(t *testing.T) {
 	zone := "country-region-zone"
 	vendorVersion := "test-version"
 	tmpDir := "/tmp/csi"
+	extraLabels := map[string]string{"test-label": "test-label-value"}
 	endpoint := fmt.Sprintf("unix:%s/csi.sock", tmpDir)
 	mountPath := path.Join(tmpDir, "mount")
 	stagePath := path.Join(tmpDir, "stage")
@@ -57,7 +58,7 @@ func TestSanity(t *testing.T) {
 	identityServer := driver.NewIdentityServer(gceDriver)
 	controllerServer := driver.NewControllerServer(gceDriver, cloudProvider)
 	nodeServer := driver.NewNodeServer(gceDriver, mounter, deviceUtils, metadataservice.NewFakeService(), mountmanager.NewFakeStatter(mounter))
-	err = gceDriver.SetupGCEDriver(driverName, vendorVersion, identityServer, controllerServer, nodeServer)
+	err = gceDriver.SetupGCEDriver(driverName, vendorVersion, extraLabels, identityServer, controllerServer, nodeServer)
 	if err != nil {
 		t.Fatalf("Failed to initialize GCE CSI Driver: %v", err)
 	}