Upgrade Zookeeper Operator to v0.2.15 (#550)

diff --git a/NOTICE b/NOTICE
index 6482ebc..8f54de3 100644
--- a/NOTICE
+++ b/NOTICE
@@ -38,6 +38,4 @@
 
 The Zookeeper Operator is used as an optional dependency, however the ZookeeperCluster CRD is used within the repository.
     config/dependencies/zookeeper_cluster_crd.yaml
-The API code was also copied to the following directory
-    controllers/zk_api
-This was taken from https://github.com/pravega/zookeeper-operator (version v0.2.14)
+This was taken from https://github.com/pravega/zookeeper-operator (version v0.2.15)
diff --git a/api/v1beta1/solrcloud_types.go b/api/v1beta1/solrcloud_types.go
index ad5c66a..c8b77c6 100644
--- a/api/v1beta1/solrcloud_types.go
+++ b/api/v1beta1/solrcloud_types.go
@@ -19,8 +19,8 @@
 
 import (
 	"fmt"
-	"github.com/apache/solr-operator/controllers/zk_api"
 	"github.com/go-logr/logr"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	"strconv"
 	"strings"
 
@@ -852,7 +852,7 @@
 	// Probes specifies the timeout values for the Readiness and Liveness Probes
 	// for the zookeeper pods.
 	// +optional
-	Probes *zk_api.Probes `json:"probes,omitempty"`
+	Probes *zkApi.Probes `json:"probes,omitempty"`
 }
 
 type ZKPersistence struct {
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index 0e42baf..8f48453 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -23,7 +23,7 @@
 package v1beta1
 
 import (
-	"github.com/apache/solr-operator/controllers/zk_api"
+	apiv1beta1 "github.com/pravega/zookeeper-operator/api/v1beta1"
 	"k8s.io/api/core/v1"
 	runtime "k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/intstr"
@@ -1598,7 +1598,7 @@
 	in.Config.DeepCopyInto(&out.Config)
 	if in.Probes != nil {
 		in, out := &in.Probes, &out.Probes
-		*out = new(zk_api.Probes)
+		*out = new(apiv1beta1.Probes)
 		(*in).DeepCopyInto(*out)
 	}
 }
diff --git a/config/dependencies/zookeeper_cluster_crd.yaml b/config/dependencies/zookeeper_cluster_crd.yaml
index 0991866..236c8c9 100644
--- a/config/dependencies/zookeeper_cluster_crd.yaml
+++ b/config/dependencies/zookeeper_cluster_crd.yaml
@@ -6,18 +6,17 @@
 #
 # http://www.apache.org/licenses/LICENSE-2.0
 #
-# Find source at: https://github.com/pravega/zookeeper-operator/tree/v0.2.14
+# Find source at: https://github.com/pravega/zookeeper-operator/tree/v0.2.15
 
 ---
-
 ---
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    operator.zookeeper.pravega.io/version: v0.2.14
+    operator.zookeeper.pravega.io/version: v0.2.15
     argocd.argoproj.io/sync-options: Replace=true
-    controller-gen.kubebuilder.io/version: v0.6.2
+    controller-gen.kubebuilder.io/version: v0.9.0
   creationTimestamp: null
   name: zookeeperclusters.zookeeper.pravega.io
 spec:
@@ -201,7 +200,7 @@
                     within a pod.
                   properties:
                     args:
-                      description: 'Arguments to the entrypoint. The docker image''s
+                      description: 'Arguments to the entrypoint. The container image''s
                         CMD is used if this is not provided. Variable references $(VAR_NAME)
                         are expanded using the container''s environment. If a variable
                         cannot be resolved, the reference in the input string will
@@ -215,7 +214,7 @@
                       type: array
                     command:
                       description: 'Entrypoint array. Not executed within a shell.
-                        The docker image''s ENTRYPOINT is used if this is not provided.
+                        The container image''s ENTRYPOINT is used if this is not provided.
                         Variable references $(VAR_NAME) are expanded using the container''s
                         environment. If a variable cannot be resolved, the reference
                         in the input string will be unchanged. Double $$ are reduced
@@ -386,7 +385,7 @@
                         type: object
                       type: array
                     image:
-                      description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images
+                      description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images
                         This field is optional to allow higher level config management
                         to default or override container images in workload controllers
                         like Deployments and StatefulSets.'
@@ -616,7 +615,7 @@
                           type: integer
                         grpc:
                           description: GRPC specifies an action involving a GRPC port.
-                            This is an alpha field and requires enabling GRPCContainerProbe
+                            This is a beta field and requires enabling GRPCContainerProbe
                             feature gate.
                           properties:
                             port:
@@ -818,7 +817,7 @@
                           type: integer
                         grpc:
                           description: GRPC specifies an action involving a GRPC port.
-                            This is an alpha field and requires enabling GRPCContainerProbe
+                            This is a beta field and requires enabling GRPCContainerProbe
                             feature gate.
                           properties:
                             port:
@@ -1178,7 +1177,7 @@
                           type: integer
                         grpc:
                           description: GRPC specifies an action involving a GRPC port.
-                            This is an alpha field and requires enabling GRPCContainerProbe
+                            This is a beta field and requires enabling GRPCContainerProbe
                             feature gate.
                           properties:
                             port:
@@ -1427,22 +1426,22 @@
                       amount of local storage required for this EmptyDir volume.
                     properties:
                       medium:
-                        description: 'What type of storage medium should back this
-                          directory. The default is "" which means to use the node''s
-                          default medium. Must be an empty string (default) or Memory.
-                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
+                        description: 'medium represents what type of storage medium
+                          should back this directory. The default is "" which means
+                          to use the node''s default medium. Must be an empty string
+                          (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
                         type: string
                       sizeLimit:
                         anyOf:
                         - type: integer
                         - type: string
-                        description: 'Total amount of local storage required for this
-                          EmptyDir volume. The size limit is also applicable for memory
-                          medium. The maximum usage on memory medium EmptyDir would
-                          be the minimum value between the SizeLimit specified here
-                          and the sum of memory limits of all containers in a pod.
-                          The default is nil which means that the limit is undefined.
-                          More info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
+                        description: 'sizeLimit is the total amount of local storage
+                          required for this EmptyDir volume. The size limit is also
+                          applicable for memory medium. The maximum usage on memory
+                          medium EmptyDir would be the minimum value between the SizeLimit
+                          specified here and the sum of memory limits of all containers
+                          in a pod. The default is nil which means that the limit
+                          is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
                         pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
                         x-kubernetes-int-or-string: true
                     type: object
@@ -1481,7 +1480,7 @@
                     within a pod.
                   properties:
                     args:
-                      description: 'Arguments to the entrypoint. The docker image''s
+                      description: 'Arguments to the entrypoint. The container image''s
                         CMD is used if this is not provided. Variable references $(VAR_NAME)
                         are expanded using the container''s environment. If a variable
                         cannot be resolved, the reference in the input string will
@@ -1495,7 +1494,7 @@
                       type: array
                     command:
                       description: 'Entrypoint array. Not executed within a shell.
-                        The docker image''s ENTRYPOINT is used if this is not provided.
+                        The container image''s ENTRYPOINT is used if this is not provided.
                         Variable references $(VAR_NAME) are expanded using the container''s
                         environment. If a variable cannot be resolved, the reference
                         in the input string will be unchanged. Double $$ are reduced
@@ -1666,7 +1665,7 @@
                         type: object
                       type: array
                     image:
-                      description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images
+                      description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images
                         This field is optional to allow higher level config management
                         to default or override container images in workload controllers
                         like Deployments and StatefulSets.'
@@ -1896,7 +1895,7 @@
                           type: integer
                         grpc:
                           description: GRPC specifies an action involving a GRPC port.
-                            This is an alpha field and requires enabling GRPCContainerProbe
+                            This is a beta field and requires enabling GRPCContainerProbe
                             feature gate.
                           properties:
                             port:
@@ -2098,7 +2097,7 @@
                           type: integer
                         grpc:
                           description: GRPC specifies an action involving a GRPC port.
-                            This is an alpha field and requires enabling GRPCContainerProbe
+                            This is a beta field and requires enabling GRPCContainerProbe
                             feature gate.
                           properties:
                             port:
@@ -2458,7 +2457,7 @@
                           type: integer
                         grpc:
                           description: GRPC specifies an action involving a GRPC port.
-                            This is an alpha field and requires enabling GRPCContainerProbe
+                            This is a beta field and requires enabling GRPCContainerProbe
                             feature gate.
                           properties:
                             port:
@@ -2697,8 +2696,9 @@
               labels:
                 additionalProperties:
                   type: string
-                description: Labels specifies the labels to attach to pods the operator
-                  creates for the zookeeper cluster.
+                description: Labels specifies the labels to attach to all resources
+                  the operator creates for the zookeeper cluster, including StatefulSet,
+                  Pod, PersistentVolumeClaim, Service, ConfigMap, et al.
                 type: object
               maxUnavailableReplicas:
                 description: MaxUnavailableReplicas defines the MaxUnavailable Replicas
@@ -2731,14 +2731,14 @@
                       default persistentvolume will get created.
                     properties:
                       accessModes:
-                        description: 'AccessModes contains the desired access modes
+                        description: 'accessModes contains the desired access modes
                           the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
                         items:
                           type: string
                         type: array
                       dataSource:
-                        description: 'This field can be used to specify either: *
-                          An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
+                        description: 'dataSource field can be used to specify either:
+                          * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
                           * An existing PVC (PersistentVolumeClaim) If the provisioner
                           or an external controller can support the specified data
                           source, it will create a new volume based on the contents
@@ -2763,11 +2763,11 @@
                         - name
                         type: object
                       dataSourceRef:
-                        description: 'Specifies the object from which to populate
-                          the volume with data, if a non-empty volume is desired.
-                          This may be any local object from a non-empty API group
-                          (non core object) or a PersistentVolumeClaim object. When
-                          this field is specified, volume binding will only succeed
+                        description: 'dataSourceRef specifies the object from which
+                          to populate the volume with data, if a non-empty volume
+                          is desired. This may be any local object from a non-empty
+                          API group (non core object) or a PersistentVolumeClaim object.
+                          When this field is specified, volume binding will only succeed
                           if the type of the specified object matches some installed
                           volume populator or dynamic provisioner. This field will
                           replace the functionality of the DataSource field and as
@@ -2777,10 +2777,10 @@
                           if one of them is empty and the other is non-empty. There
                           are two important differences between DataSource and DataSourceRef:
                           * While DataSource only allows two specific types of objects,
-                          DataSourceRef   allows any non-core object, as well as PersistentVolumeClaim
+                          DataSourceRef allows any non-core object, as well as PersistentVolumeClaim
                           objects. * While DataSource ignores disallowed values (dropping
-                          them), DataSourceRef   preserves all values, and generates
-                          an error if a disallowed value is   specified. (Alpha) Using
+                          them), DataSourceRef preserves all values, and generates
+                          an error if a disallowed value is specified. (Beta) Using
                           this field requires the AnyVolumeDataSource feature gate
                           to be enabled.'
                         properties:
@@ -2801,7 +2801,7 @@
                         - name
                         type: object
                       resources:
-                        description: 'Resources represents the minimum resources the
+                        description: 'resources represents the minimum resources the
                           volume should have. If RecoverVolumeExpansionFailure feature
                           is enabled users are allowed to specify resource requirements
                           that are lower than previous value but must still be higher
@@ -2833,7 +2833,8 @@
                             type: object
                         type: object
                       selector:
-                        description: A label query over volumes to consider for binding.
+                        description: selector is a label query over volumes to consider
+                          for binding.
                         properties:
                           matchExpressions:
                             description: matchExpressions is a list of label selector
@@ -2878,8 +2879,8 @@
                             type: object
                         type: object
                       storageClassName:
-                        description: 'Name of the StorageClass required by the claim.
-                          More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+                        description: 'storageClassName is the name of the StorageClass
+                          required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
                         type: string
                       volumeMode:
                         description: volumeMode defines what type of volume is required
@@ -2887,7 +2888,7 @@
                           in claim spec.
                         type: string
                       volumeName:
-                        description: VolumeName is the binding reference to the PersistentVolume
+                        description: volumeName is the binding reference to the PersistentVolume
                           backing this claim.
                         type: string
                     type: object
@@ -3198,9 +3199,7 @@
                                         this field and the ones listed in the namespaces
                                         field. null selector and null or empty namespaces
                                         list means "this pod's namespace". An empty
-                                        selector ({}) matches all namespaces. This
-                                        field is beta-level and is only honored when
-                                        PodAffinityNamespaceSelector feature is enabled.
+                                        selector ({}) matches all namespaces.
                                       properties:
                                         matchExpressions:
                                           description: matchExpressions is a list
@@ -3257,7 +3256,7 @@
                                         listed in this field and the ones selected
                                         by namespaceSelector. null or empty namespaces
                                         list and null namespaceSelector means "this
-                                        pod's namespace"
+                                        pod's namespace".
                                       items:
                                         type: string
                                       type: array
@@ -3361,9 +3360,7 @@
                                     field and the ones listed in the namespaces field.
                                     null selector and null or empty namespaces list
                                     means "this pod's namespace". An empty selector
-                                    ({}) matches all namespaces. This field is beta-level
-                                    and is only honored when PodAffinityNamespaceSelector
-                                    feature is enabled.
+                                    ({}) matches all namespaces.
                                   properties:
                                     matchExpressions:
                                       description: matchExpressions is a list of label
@@ -3418,7 +3415,7 @@
                                     term is applied to the union of the namespaces
                                     listed in this field and the ones selected by
                                     namespaceSelector. null or empty namespaces list
-                                    and null namespaceSelector means "this pod's namespace"
+                                    and null namespaceSelector means "this pod's namespace".
                                   items:
                                     type: string
                                   type: array
@@ -3522,9 +3519,7 @@
                                         this field and the ones listed in the namespaces
                                         field. null selector and null or empty namespaces
                                         list means "this pod's namespace". An empty
-                                        selector ({}) matches all namespaces. This
-                                        field is beta-level and is only honored when
-                                        PodAffinityNamespaceSelector feature is enabled.
+                                        selector ({}) matches all namespaces.
                                       properties:
                                         matchExpressions:
                                           description: matchExpressions is a list
@@ -3581,7 +3576,7 @@
                                         listed in this field and the ones selected
                                         by namespaceSelector. null or empty namespaces
                                         list and null namespaceSelector means "this
-                                        pod's namespace"
+                                        pod's namespace".
                                       items:
                                         type: string
                                       type: array
@@ -3685,9 +3680,7 @@
                                     field and the ones listed in the namespaces field.
                                     null selector and null or empty namespaces list
                                     means "this pod's namespace". An empty selector
-                                    ({}) matches all namespaces. This field is beta-level
-                                    and is only honored when PodAffinityNamespaceSelector
-                                    feature is enabled.
+                                    ({}) matches all namespaces.
                                   properties:
                                     matchExpressions:
                                       description: matchExpressions is a list of label
@@ -3742,7 +3735,7 @@
                                     term is applied to the union of the namespaces
                                     listed in this field and the ones selected by
                                     namespaceSelector. null or empty namespaces list
-                                    and null namespaceSelector means "this pod's namespace"
+                                    and null namespaceSelector means "this pod's namespace".
                                   items:
                                     type: string
                                   type: array
@@ -3895,7 +3888,8 @@
                     additionalProperties:
                       type: string
                     description: Labels specifies the labels to attach to pods the
-                      operator creates for the zookeeper cluster.
+                      operator creates for the zookeeper cluster. Overrides any values
+                      specified in Spec.Labels.
                     type: object
                   nodeSelector:
                     additionalProperties:
@@ -4153,6 +4147,144 @@
                           type: string
                       type: object
                     type: array
+                  topologySpreadConstraints:
+                    description: TopologySpreadConstraints to apply to the pods
+                    items:
+                      description: TopologySpreadConstraint specifies how to spread
+                        matching pods among the given topology.
+                      properties:
+                        labelSelector:
+                          description: LabelSelector is used to find matching pods.
+                            Pods that match this label selector are counted to determine
+                            the number of pods in their corresponding topology domain.
+                          properties:
+                            matchExpressions:
+                              description: matchExpressions is a list of label selector
+                                requirements. The requirements are ANDed.
+                              items:
+                                description: A label selector requirement is a selector
+                                  that contains values, a key, and an operator that
+                                  relates the key and values.
+                                properties:
+                                  key:
+                                    description: key is the label key that the selector
+                                      applies to.
+                                    type: string
+                                  operator:
+                                    description: operator represents a key's relationship
+                                      to a set of values. Valid operators are In,
+                                      NotIn, Exists and DoesNotExist.
+                                    type: string
+                                  values:
+                                    description: values is an array of string values.
+                                      If the operator is In or NotIn, the values array
+                                      must be non-empty. If the operator is Exists
+                                      or DoesNotExist, the values array must be empty.
+                                      This array is replaced during a strategic merge
+                                      patch.
+                                    items:
+                                      type: string
+                                    type: array
+                                required:
+                                - key
+                                - operator
+                                type: object
+                              type: array
+                            matchLabels:
+                              additionalProperties:
+                                type: string
+                              description: matchLabels is a map of {key,value} pairs.
+                                A single {key,value} in the matchLabels map is equivalent
+                                to an element of matchExpressions, whose key field
+                                is "key", the operator is "In", and the values array
+                                contains only "value". The requirements are ANDed.
+                              type: object
+                          type: object
+                        maxSkew:
+                          description: 'MaxSkew describes the degree to which pods
+                            may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`,
+                            it is the maximum permitted difference between the number
+                            of matching pods in the target topology and the global
+                            minimum. The global minimum is the minimum number of matching
+                            pods in an eligible domain or zero if the number of eligible
+                            domains is less than MinDomains. For example, in a 3-zone
+                            cluster, MaxSkew is set to 1, and pods with the same labelSelector
+                            spread as 2/2/1: In this case, the global minimum is 1.
+                            | zone1 | zone2 | zone3 | |  P P  |  P P  |   P   | -
+                            if MaxSkew is 1, incoming pod can only be scheduled to
+                            zone3 to become 2/2/2; scheduling it onto zone1(zone2)
+                            would make the ActualSkew(3-1) on zone1(zone2) violate
+                            MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled
+                            onto any zone. When `whenUnsatisfiable=ScheduleAnyway`,
+                            it is used to give higher precedence to topologies that
+                            satisfy it. It''s a required field. Default value is 1
+                            and 0 is not allowed.'
+                          format: int32
+                          type: integer
+                        minDomains:
+                          description: "MinDomains indicates a minimum number of eligible
+                            domains. When the number of eligible domains with matching
+                            topology keys is less than minDomains, Pod Topology Spread
+                            treats \"global minimum\" as 0, and then the calculation
+                            of Skew is performed. And when the number of eligible
+                            domains with matching topology keys equals or greater
+                            than minDomains, this value has no effect on scheduling.
+                            As a result, when the number of eligible domains is less
+                            than minDomains, scheduler won't schedule more than maxSkew
+                            Pods to those domains. If value is nil, the constraint
+                            behaves as if MinDomains is equal to 1. Valid values are
+                            integers greater than 0. When value is not nil, WhenUnsatisfiable
+                            must be DoNotSchedule. \n For example, in a 3-zone cluster,
+                            MaxSkew is set to 2, MinDomains is set to 5 and pods with
+                            the same labelSelector spread as 2/2/2: | zone1 | zone2
+                            | zone3 | |  P P  |  P P  |  P P  | The number of domains
+                            is less than 5(MinDomains), so \"global minimum\" is treated
+                            as 0. In this situation, new pod with the same labelSelector
+                            cannot be scheduled, because computed skew will be 3(3
+                            - 0) if new Pod is scheduled to any of the three zones,
+                            it will violate MaxSkew. \n This is an alpha field and
+                            requires enabling MinDomainsInPodTopologySpread feature
+                            gate."
+                          format: int32
+                          type: integer
+                        topologyKey:
+                          description: TopologyKey is the key of node labels. Nodes
+                            that have a label with this key and identical values are
+                            considered to be in the same topology. We consider each
+                            <key, value> as a "bucket", and try to put balanced number
+                            of pods into each bucket. We define a domain as a particular
+                            instance of a topology. Also, we define an eligible domain
+                            as a domain whose nodes match the node selector. e.g.
+                            If TopologyKey is "kubernetes.io/hostname", each Node
+                            is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone",
+                            each zone is a domain of that topology. It's a required
+                            field.
+                          type: string
+                        whenUnsatisfiable:
+                          description: 'WhenUnsatisfiable indicates how to deal with
+                            a pod if it doesn''t satisfy the spread constraint. -
+                            DoNotSchedule (default) tells the scheduler not to schedule
+                            it. - ScheduleAnyway tells the scheduler to schedule the
+                            pod in any location, but giving higher precedence to topologies
+                            that would help reduce the skew. A constraint is considered
+                            "Unsatisfiable" for an incoming pod if and only if every
+                            possible node assignment for that pod would violate "MaxSkew"
+                            on some topology. For example, in a 3-zone cluster, MaxSkew
+                            is set to 1, and pods with the same labelSelector spread
+                            as 3/1/1: | zone1 | zone2 | zone3 | | P P P |   P   |   P   |
+                            If WhenUnsatisfiable is set to DoNotSchedule, incoming
+                            pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2)
+                            as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1).
+                            In other words, the cluster can still be imbalanced, but
+                            scheduler won''t make it *more* imbalanced. It''s a required
+                            field.'
+                          type: string
+                      required:
+                      - maxSkew
+                      - topologyKey
+                      - whenUnsatisfiable
+                      type: object
+                    type: array
                 type: object
               ports:
                 items:
@@ -4304,117 +4436,121 @@
                     be accessed by any container in the pod.
                   properties:
                     awsElasticBlockStore:
-                      description: 'AWSElasticBlockStore represents an AWS Disk resource
+                      description: 'awsElasticBlockStore represents an AWS Disk resource
                         that is attached to a kubelet''s host machine and then exposed
                         to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
                       properties:
                         fsType:
-                          description: 'Filesystem type of the volume that you want
-                            to mount. Tip: Ensure that the filesystem type is supported
-                            by the host operating system. Examples: "ext4", "xfs",
-                            "ntfs". Implicitly inferred to be "ext4" if unspecified.
-                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
+                          description: 'fsType is the filesystem type of the volume
+                            that you want to mount. Tip: Ensure that the filesystem
+                            type is supported by the host operating system. Examples:
+                            "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
                             TODO: how do we prevent errors in the filesystem from
                             compromising the machine'
                           type: string
                         partition:
-                          description: 'The partition in the volume that you want
-                            to mount. If omitted, the default is to mount by volume
-                            name. Examples: For volume /dev/sda1, you specify the
-                            partition as "1". Similarly, the volume partition for
-                            /dev/sda is "0" (or you can leave the property empty).'
+                          description: 'partition is the partition in the volume that
+                            you want to mount. If omitted, the default is to mount
+                            by volume name. Examples: For volume /dev/sda1, you specify
+                            the partition as "1". Similarly, the volume partition
+                            for /dev/sda is "0" (or you can leave the property empty).'
                           format: int32
                           type: integer
                         readOnly:
-                          description: 'Specify "true" to force and set the ReadOnly
-                            property in VolumeMounts to "true". If omitted, the default
-                            is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+                          description: 'readOnly value true will force the readOnly
+                            setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
                           type: boolean
                         volumeID:
-                          description: 'Unique ID of the persistent disk resource
-                            in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
+                          description: 'volumeID is unique ID of the persistent disk
+                            resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore'
                           type: string
                       required:
                       - volumeID
                       type: object
                     azureDisk:
-                      description: AzureDisk represents an Azure Data Disk mount on
+                      description: azureDisk represents an Azure Data Disk mount on
                         the host and bind mount to the pod.
                       properties:
                         cachingMode:
-                          description: 'Host Caching mode: None, Read Only, Read Write.'
+                          description: 'cachingMode is the Host Caching mode: None,
+                            Read Only, Read Write.'
                           type: string
                         diskName:
-                          description: The Name of the data disk in the blob storage
+                          description: diskName is the Name of the data disk in the
+                            blob storage
                           type: string
                         diskURI:
-                          description: The URI the data disk in the blob storage
+                          description: diskURI is the URI of data disk in the blob
+                            storage
                           type: string
                         fsType:
-                          description: Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Ex. "ext4",
-                            "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+                          description: fsType is Filesystem type to mount. Must be
+                            a filesystem type supported by the host operating system.
+                            Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified.
                           type: string
                         kind:
-                          description: 'Expected values Shared: multiple blob disks
-                            per storage account  Dedicated: single blob disk per storage
-                            account  Managed: azure managed data disk (only in managed
-                            availability set). defaults to shared'
+                          description: 'kind expected values are Shared: multiple
+                            blob disks per storage account  Dedicated: single blob
+                            disk per storage account  Managed: azure managed data
+                            disk (only in managed availability set). defaults to shared'
                           type: string
                         readOnly:
-                          description: Defaults to false (read/write). ReadOnly here
-                            will force the ReadOnly setting in VolumeMounts.
+                          description: readOnly Defaults to false (read/write). ReadOnly
+                            here will force the ReadOnly setting in VolumeMounts.
                           type: boolean
                       required:
                       - diskName
                       - diskURI
                       type: object
                     azureFile:
-                      description: AzureFile represents an Azure File Service mount
+                      description: azureFile represents an Azure File Service mount
                         on the host and bind mount to the pod.
                       properties:
                         readOnly:
-                          description: Defaults to false (read/write). ReadOnly here
-                            will force the ReadOnly setting in VolumeMounts.
+                          description: readOnly defaults to false (read/write). ReadOnly
+                            here will force the ReadOnly setting in VolumeMounts.
                           type: boolean
                         secretName:
-                          description: the name of secret that contains Azure Storage
-                            Account Name and Key
+                          description: secretName is the  name of secret that contains
+                            Azure Storage Account Name and Key
                           type: string
                         shareName:
-                          description: Share Name
+                          description: shareName is the azure share Name
                           type: string
                       required:
                       - secretName
                       - shareName
                       type: object
                     cephfs:
-                      description: CephFS represents a Ceph FS mount on the host that
+                      description: cephFS represents a Ceph FS mount on the host that
                         shares a pod's lifetime
                       properties:
                         monitors:
-                          description: 'Required: Monitors is a collection of Ceph
-                            monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+                          description: 'monitors is Required: Monitors is a collection
+                            of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
                           items:
                             type: string
                           type: array
                         path:
-                          description: 'Optional: Used as the mounted root, rather
-                            than the full Ceph tree, default is /'
+                          description: 'path is Optional: Used as the mounted root,
+                            rather than the full Ceph tree, default is /'
                           type: string
                         readOnly:
-                          description: 'Optional: Defaults to false (read/write).
+                          description: 'readOnly is Optional: Defaults to false (read/write).
                             ReadOnly here will force the ReadOnly setting in VolumeMounts.
                             More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
                           type: boolean
                         secretFile:
-                          description: 'Optional: SecretFile is the path to key ring
-                            for User, default is /etc/ceph/user.secret More info:
-                            https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+                          description: 'secretFile is Optional: SecretFile is the
+                            path to key ring for User, default is /etc/ceph/user.secret
+                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
                           type: string
                         secretRef:
-                          description: 'Optional: SecretRef is reference to the authentication
-                            secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+                          description: 'secretRef is Optional: SecretRef is reference
+                            to the authentication secret for User, default is empty.
+                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
                           properties:
                             name:
                               description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
@@ -4422,30 +4558,30 @@
                               type: string
                           type: object
                         user:
-                          description: 'Optional: User is the rados user name, default
-                            is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
+                          description: 'user is optional: User is the rados user name,
+                            default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it'
                           type: string
                       required:
                       - monitors
                       type: object
                     cinder:
-                      description: 'Cinder represents a cinder volume attached and
+                      description: 'cinder represents a cinder volume attached and
                         mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
                       properties:
                         fsType:
-                          description: 'Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Examples:
-                            "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
-                            if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
+                          description: 'fsType is the filesystem type to mount. Must
+                            be a filesystem type supported by the host operating system.
+                            Examples: "ext4", "xfs", "ntfs". Implicitly inferred to
+                            be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
                           type: string
                         readOnly:
-                          description: 'Optional: Defaults to false (read/write).
-                            ReadOnly here will force the ReadOnly setting in VolumeMounts.
+                          description: 'readOnly defaults to false (read/write). ReadOnly
+                            here will force the ReadOnly setting in VolumeMounts.
                             More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
                           type: boolean
                         secretRef:
-                          description: 'Optional: points to a secret object containing
-                            parameters used to connect to OpenStack.'
+                          description: 'secretRef is optional: points to a secret
+                            object containing parameters used to connect to OpenStack.'
                           properties:
                             name:
                               description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
@@ -4453,31 +4589,31 @@
                               type: string
                           type: object
                         volumeID:
-                          description: 'volume id used to identify the volume in cinder.
+                          description: 'volumeID used to identify the volume in cinder.
                             More info: https://examples.k8s.io/mysql-cinder-pd/README.md'
                           type: string
                       required:
                       - volumeID
                       type: object
                     configMap:
-                      description: ConfigMap represents a configMap that should populate
+                      description: configMap represents a configMap that should populate
                         this volume
                       properties:
                         defaultMode:
-                          description: 'Optional: mode bits used to set permissions
-                            on created files by default. Must be an octal value between
-                            0000 and 0777 or a decimal value between 0 and 511. YAML
-                            accepts both octal and decimal values, JSON requires decimal
-                            values for mode bits. Defaults to 0644. Directories within
-                            the path are not affected by this setting. This might
-                            be in conflict with other options that affect the file
-                            mode, like fsGroup, and the result can be other mode bits
-                            set.'
+                          description: 'defaultMode is optional: mode bits used to
+                            set permissions on created files by default. Must be an
+                            octal value between 0000 and 0777 or a decimal value between
+                            0 and 511. YAML accepts both octal and decimal values,
+                            JSON requires decimal values for mode bits. Defaults to
+                            0644. Directories within the path are not affected by
+                            this setting. This might be in conflict with other options
+                            that affect the file mode, like fsGroup, and the result
+                            can be other mode bits set.'
                           format: int32
                           type: integer
                         items:
-                          description: If unspecified, each key-value pair in the
-                            Data field of the referenced ConfigMap will be projected
+                          description: items if unspecified, each key-value pair in
+                            the Data field of the referenced ConfigMap will be projected
                             into the volume as a file whose name is the key and content
                             is the value. If specified, the listed keys will be projected
                             into the specified paths, and unlisted keys will not be
@@ -4489,25 +4625,25 @@
                             description: Maps a string key to a path within a volume.
                             properties:
                               key:
-                                description: The key to project.
+                                description: key is the key to project.
                                 type: string
                               mode:
-                                description: 'Optional: mode bits used to set permissions
-                                  on this file. Must be an octal value between 0000
-                                  and 0777 or a decimal value between 0 and 511. YAML
-                                  accepts both octal and decimal values, JSON requires
-                                  decimal values for mode bits. If not specified,
-                                  the volume defaultMode will be used. This might
-                                  be in conflict with other options that affect the
-                                  file mode, like fsGroup, and the result can be other
-                                  mode bits set.'
+                                description: 'mode is Optional: mode bits used to
+                                  set permissions on this file. Must be an octal value
+                                  between 0000 and 0777 or a decimal value between
+                                  0 and 511. YAML accepts both octal and decimal values,
+                                  JSON requires decimal values for mode bits. If not
+                                  specified, the volume defaultMode will be used.
+                                  This might be in conflict with other options that
+                                  affect the file mode, like fsGroup, and the result
+                                  can be other mode bits set.'
                                 format: int32
                                 type: integer
                               path:
-                                description: The relative path of the file to map
-                                  the key to. May not be an absolute path. May not
-                                  contain the path element '..'. May not start with
-                                  the string '..'.
+                                description: path is the relative path of the file
+                                  to map the key to. May not be an absolute path.
+                                  May not contain the path element '..'. May not start
+                                  with the string '..'.
                                 type: string
                             required:
                             - key
@@ -4519,28 +4655,28 @@
                             TODO: Add other useful fields. apiVersion, kind, uid?'
                           type: string
                         optional:
-                          description: Specify whether the ConfigMap or its keys must
-                            be defined
+                          description: optional specify whether the ConfigMap or its
+                            keys must be defined
                           type: boolean
                       type: object
                     csi:
-                      description: CSI (Container Storage Interface) represents ephemeral
+                      description: csi (Container Storage Interface) represents ephemeral
                         storage that is handled by certain external CSI drivers (Beta
                         feature).
                       properties:
                         driver:
-                          description: Driver is the name of the CSI driver that handles
+                          description: driver is the name of the CSI driver that handles
                             this volume. Consult with your admin for the correct name
                             as registered in the cluster.
                           type: string
                         fsType:
-                          description: Filesystem type to mount. Ex. "ext4", "xfs",
-                            "ntfs". If not provided, the empty value is passed to
-                            the associated CSI driver which will determine the default
-                            filesystem to apply.
+                          description: fsType to mount. Ex. "ext4", "xfs", "ntfs".
+                            If not provided, the empty value is passed to the associated
+                            CSI driver which will determine the default filesystem
+                            to apply.
                           type: string
                         nodePublishSecretRef:
-                          description: NodePublishSecretRef is a reference to the
+                          description: nodePublishSecretRef is a reference to the
                             secret object containing sensitive information to pass
                             to the CSI driver to complete the CSI NodePublishVolume
                             and NodeUnpublishVolume calls. This field is optional,
@@ -4554,13 +4690,13 @@
                               type: string
                           type: object
                         readOnly:
-                          description: Specifies a read-only configuration for the
-                            volume. Defaults to false (read/write).
+                          description: readOnly specifies a read-only configuration
+                            for the volume. Defaults to false (read/write).
                           type: boolean
                         volumeAttributes:
                           additionalProperties:
                             type: string
-                          description: VolumeAttributes stores driver-specific properties
+                          description: volumeAttributes stores driver-specific properties
                             that are passed to the CSI driver. Consult your driver's
                             documentation for supported values.
                           type: object
@@ -4568,7 +4704,7 @@
                       - driver
                       type: object
                     downwardAPI:
-                      description: DownwardAPI represents downward API about the pod
+                      description: downwardAPI represents downward API about the pod
                         that should populate this volume
                       properties:
                         defaultMode:
@@ -4655,48 +4791,47 @@
                           type: array
                       type: object
                     emptyDir:
-                      description: 'EmptyDir represents a temporary directory that
+                      description: 'emptyDir represents a temporary directory that
                         shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
                       properties:
                         medium:
-                          description: 'What type of storage medium should back this
-                            directory. The default is "" which means to use the node''s
-                            default medium. Must be an empty string (default) or Memory.
-                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
+                          description: 'medium represents what type of storage medium
+                            should back this directory. The default is "" which means
+                            to use the node''s default medium. Must be an empty string
+                            (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
                           type: string
                         sizeLimit:
                           anyOf:
                           - type: integer
                           - type: string
-                          description: 'Total amount of local storage required for
-                            this EmptyDir volume. The size limit is also applicable
-                            for memory medium. The maximum usage on memory medium
-                            EmptyDir would be the minimum value between the SizeLimit
-                            specified here and the sum of memory limits of all containers
-                            in a pod. The default is nil which means that the limit
-                            is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
+                          description: 'sizeLimit is the total amount of local storage
+                            required for this EmptyDir volume. The size limit is also
+                            applicable for memory medium. The maximum usage on memory
+                            medium EmptyDir would be the minimum value between the
+                            SizeLimit specified here and the sum of memory limits
+                            of all containers in a pod. The default is nil which means
+                            that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
                           pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
                           x-kubernetes-int-or-string: true
                       type: object
                     ephemeral:
-                      description: "Ephemeral represents a volume that is handled
+                      description: "ephemeral represents a volume that is handled
                         by a cluster storage driver. The volume's lifecycle is tied
                         to the pod that defines it - it will be created before the
                         pod starts, and deleted when the pod is removed. \n Use this
                         if: a) the volume is only needed while the pod runs, b) features
                         of normal volumes like restoring from snapshot or capacity
-                        \   tracking are needed, c) the storage driver is specified
-                        through a storage class, and d) the storage driver supports
-                        dynamic volume provisioning through    a PersistentVolumeClaim
-                        (see EphemeralVolumeSource for more    information on the
-                        connection between this volume type    and PersistentVolumeClaim).
-                        \n Use PersistentVolumeClaim or one of the vendor-specific
-                        APIs for volumes that persist for longer than the lifecycle
-                        of an individual pod. \n Use CSI for light-weight local ephemeral
-                        volumes if the CSI driver is meant to be used that way - see
-                        the documentation of the driver for more information. \n A
-                        pod can use both types of ephemeral volumes and persistent
-                        volumes at the same time."
+                        tracking are needed, c) the storage driver is specified through
+                        a storage class, and d) the storage driver supports dynamic
+                        volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource
+                        for more information on the connection between this volume
+                        type and PersistentVolumeClaim). \n Use PersistentVolumeClaim
+                        or one of the vendor-specific APIs for volumes that persist
+                        for longer than the lifecycle of an individual pod. \n Use
+                        CSI for light-weight local ephemeral volumes if the CSI driver
+                        is meant to be used that way - see the documentation of the
+                        driver for more information. \n A pod can use both types of
+                        ephemeral volumes and persistent volumes at the same time."
                       properties:
                         volumeClaimTemplate:
                           description: "Will be used to create a stand-alone PVC to
@@ -4731,13 +4866,13 @@
                                 as in a PersistentVolumeClaim are also valid here.
                               properties:
                                 accessModes:
-                                  description: 'AccessModes contains the desired access
+                                  description: 'accessModes contains the desired access
                                     modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1'
                                   items:
                                     type: string
                                   type: array
                                 dataSource:
-                                  description: 'This field can be used to specify
+                                  description: 'dataSource field can be used to specify
                                     either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)
                                     * An existing PVC (PersistentVolumeClaim) If the
                                     provisioner or an external controller can support
@@ -4767,14 +4902,14 @@
                                   - name
                                   type: object
                                 dataSourceRef:
-                                  description: 'Specifies the object from which to
-                                    populate the volume with data, if a non-empty
-                                    volume is desired. This may be any local object
-                                    from a non-empty API group (non core object) or
-                                    a PersistentVolumeClaim object. When this field
-                                    is specified, volume binding will only succeed
-                                    if the type of the specified object matches some
-                                    installed volume populator or dynamic provisioner.
+                                  description: 'dataSourceRef specifies the object
+                                    from which to populate the volume with data, if
+                                    a non-empty volume is desired. This may be any
+                                    local object from a non-empty API group (non core
+                                    object) or a PersistentVolumeClaim object. When
+                                    this field is specified, volume binding will only
+                                    succeed if the type of the specified object matches
+                                    some installed volume populator or dynamic provisioner.
                                     This field will replace the functionality of the
                                     DataSource field and as such if both fields are
                                     non-empty, they must have the same value. For
@@ -4784,13 +4919,13 @@
                                     other is non-empty. There are two important differences
                                     between DataSource and DataSourceRef: * While
                                     DataSource only allows two specific types of objects,
-                                    DataSourceRef   allows any non-core object, as
-                                    well as PersistentVolumeClaim objects. * While
-                                    DataSource ignores disallowed values (dropping
-                                    them), DataSourceRef   preserves all values, and
-                                    generates an error if a disallowed value is   specified.
-                                    (Alpha) Using this field requires the AnyVolumeDataSource
-                                    feature gate to be enabled.'
+                                    DataSourceRef allows any non-core object, as well
+                                    as PersistentVolumeClaim objects. * While DataSource
+                                    ignores disallowed values (dropping them), DataSourceRef
+                                    preserves all values, and generates an error if
+                                    a disallowed value is specified. (Beta) Using
+                                    this field requires the AnyVolumeDataSource feature
+                                    gate to be enabled.'
                                   properties:
                                     apiGroup:
                                       description: APIGroup is the group for the resource
@@ -4812,7 +4947,7 @@
                                   - name
                                   type: object
                                 resources:
-                                  description: 'Resources represents the minimum resources
+                                  description: 'resources represents the minimum resources
                                     the volume should have. If RecoverVolumeExpansionFailure
                                     feature is enabled users are allowed to specify
                                     resource requirements that are lower than previous
@@ -4845,8 +4980,8 @@
                                       type: object
                                   type: object
                                 selector:
-                                  description: A label query over volumes to consider
-                                    for binding.
+                                  description: selector is a label query over volumes
+                                    to consider for binding.
                                   properties:
                                     matchExpressions:
                                       description: matchExpressions is a list of label
@@ -4896,8 +5031,9 @@
                                       type: object
                                   type: object
                                 storageClassName:
-                                  description: 'Name of the StorageClass required
-                                    by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
+                                  description: 'storageClassName is the name of the
+                                    StorageClass required by the claim. More info:
+                                    https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1'
                                   type: string
                                 volumeMode:
                                   description: volumeMode defines what type of volume
@@ -4905,7 +5041,7 @@
                                     is implied when not included in claim spec.
                                   type: string
                                 volumeName:
-                                  description: VolumeName is the binding reference
+                                  description: volumeName is the binding reference
                                     to the PersistentVolume backing this claim.
                                   type: string
                               type: object
@@ -4914,32 +5050,33 @@
                           type: object
                       type: object
                     fc:
-                      description: FC represents a Fibre Channel resource that is
+                      description: fc represents a Fibre Channel resource that is
                         attached to a kubelet's host machine and then exposed to the
                         pod.
                       properties:
                         fsType:
-                          description: 'Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Ex. "ext4",
-                            "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
-                            TODO: how do we prevent errors in the filesystem from
-                            compromising the machine'
+                          description: 'fsType is the filesystem type to mount. Must
+                            be a filesystem type supported by the host operating system.
+                            Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified. TODO: how do we prevent errors in the
+                            filesystem from compromising the machine'
                           type: string
                         lun:
-                          description: 'Optional: FC target lun number'
+                          description: 'lun is Optional: FC target lun number'
                           format: int32
                           type: integer
                         readOnly:
-                          description: 'Optional: Defaults to false (read/write).
+                          description: 'readOnly is Optional: Defaults to false (read/write).
                             ReadOnly here will force the ReadOnly setting in VolumeMounts.'
                           type: boolean
                         targetWWNs:
-                          description: 'Optional: FC target worldwide names (WWNs)'
+                          description: 'targetWWNs is Optional: FC target worldwide
+                            names (WWNs)'
                           items:
                             type: string
                           type: array
                         wwids:
-                          description: 'Optional: FC volume world wide identifiers
+                          description: 'wwids Optional: FC volume world wide identifiers
                             (wwids) Either wwids or combination of targetWWNs and
                             lun must be set, but not both simultaneously.'
                           items:
@@ -4947,34 +5084,36 @@
                           type: array
                       type: object
                     flexVolume:
-                      description: FlexVolume represents a generic volume resource
+                      description: flexVolume represents a generic volume resource
                         that is provisioned/attached using an exec based plugin.
                       properties:
                         driver:
-                          description: Driver is the name of the driver to use for
+                          description: driver is the name of the driver to use for
                             this volume.
                           type: string
                         fsType:
-                          description: Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Ex. "ext4",
-                            "xfs", "ntfs". The default filesystem depends on FlexVolume
-                            script.
+                          description: fsType is the filesystem type to mount. Must
+                            be a filesystem type supported by the host operating system.
+                            Ex. "ext4", "xfs", "ntfs". The default filesystem depends
+                            on FlexVolume script.
                           type: string
                         options:
                           additionalProperties:
                             type: string
-                          description: 'Optional: Extra command options if any.'
+                          description: 'options is Optional: this field holds extra
+                            command options if any.'
                           type: object
                         readOnly:
-                          description: 'Optional: Defaults to false (read/write).
+                          description: 'readOnly is Optional: defaults to false (read/write).
                             ReadOnly here will force the ReadOnly setting in VolumeMounts.'
                           type: boolean
                         secretRef:
-                          description: 'Optional: SecretRef is reference to the secret
-                            object containing sensitive information to pass to the
-                            plugin scripts. This may be empty if no secret object
-                            is specified. If the secret object contains more than
-                            one secret, all secrets are passed to the plugin scripts.'
+                          description: 'secretRef is Optional: secretRef is reference
+                            to the secret object containing sensitive information
+                            to pass to the plugin scripts. This may be empty if no
+                            secret object is specified. If the secret object contains
+                            more than one secret, all secrets are passed to the plugin
+                            scripts.'
                           properties:
                             name:
                               description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
@@ -4985,90 +5124,92 @@
                       - driver
                       type: object
                     flocker:
-                      description: Flocker represents a Flocker volume attached to
+                      description: flocker represents a Flocker volume attached to
                         a kubelet's host machine. This depends on the Flocker control
                         service being running
                       properties:
                         datasetName:
-                          description: Name of the dataset stored as metadata -> name
-                            on the dataset for Flocker should be considered as deprecated
+                          description: datasetName is Name of the dataset stored as
+                            metadata -> name on the dataset for Flocker should be
+                            considered as deprecated
                           type: string
                         datasetUUID:
-                          description: UUID of the dataset. This is unique identifier
-                            of a Flocker dataset
+                          description: datasetUUID is the UUID of the dataset. This
+                            is unique identifier of a Flocker dataset
                           type: string
                       type: object
                     gcePersistentDisk:
-                      description: 'GCEPersistentDisk represents a GCE Disk resource
+                      description: 'gcePersistentDisk represents a GCE Disk resource
                         that is attached to a kubelet''s host machine and then exposed
                         to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
                       properties:
                         fsType:
-                          description: 'Filesystem type of the volume that you want
-                            to mount. Tip: Ensure that the filesystem type is supported
-                            by the host operating system. Examples: "ext4", "xfs",
-                            "ntfs". Implicitly inferred to be "ext4" if unspecified.
+                          description: 'fsType is filesystem type of the volume that
+                            you want to mount. Tip: Ensure that the filesystem type
+                            is supported by the host operating system. Examples: "ext4",
+                            "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
                             More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
                             TODO: how do we prevent errors in the filesystem from
                             compromising the machine'
                           type: string
                         partition:
-                          description: 'The partition in the volume that you want
-                            to mount. If omitted, the default is to mount by volume
-                            name. Examples: For volume /dev/sda1, you specify the
-                            partition as "1". Similarly, the volume partition for
-                            /dev/sda is "0" (or you can leave the property empty).
+                          description: 'partition is the partition in the volume that
+                            you want to mount. If omitted, the default is to mount
+                            by volume name. Examples: For volume /dev/sda1, you specify
+                            the partition as "1". Similarly, the volume partition
+                            for /dev/sda is "0" (or you can leave the property empty).
                             More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
                           format: int32
                           type: integer
                         pdName:
-                          description: 'Unique name of the PD resource in GCE. Used
-                            to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
+                          description: 'pdName is unique name of the PD resource in
+                            GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
                           type: string
                         readOnly:
-                          description: 'ReadOnly here will force the ReadOnly setting
+                          description: 'readOnly here will force the ReadOnly setting
                             in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk'
                           type: boolean
                       required:
                       - pdName
                       type: object
                     gitRepo:
-                      description: 'GitRepo represents a git repository at a particular
+                      description: 'gitRepo represents a git repository at a particular
                         revision. DEPRECATED: GitRepo is deprecated. To provision
                         a container with a git repo, mount an EmptyDir into an InitContainer
                         that clones the repo using git, then mount the EmptyDir into
                         the Pod''s container.'
                       properties:
                         directory:
-                          description: Target directory name. Must not contain or
-                            start with '..'.  If '.' is supplied, the volume directory
-                            will be the git repository.  Otherwise, if specified,
-                            the volume will contain the git repository in the subdirectory
-                            with the given name.
+                          description: directory is the target directory name. Must
+                            not contain or start with '..'.  If '.' is supplied, the
+                            volume directory will be the git repository.  Otherwise,
+                            if specified, the volume will contain the git repository
+                            in the subdirectory with the given name.
                           type: string
                         repository:
-                          description: Repository URL
+                          description: repository is the URL
                           type: string
                         revision:
-                          description: Commit hash for the specified revision.
+                          description: revision is the commit hash for the specified
+                            revision.
                           type: string
                       required:
                       - repository
                       type: object
                     glusterfs:
-                      description: 'Glusterfs represents a Glusterfs mount on the
+                      description: 'glusterfs represents a Glusterfs mount on the
                         host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md'
                       properties:
                         endpoints:
-                          description: 'EndpointsName is the endpoint name that details
+                          description: 'endpoints is the endpoint name that details
                             Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
                           type: string
                         path:
-                          description: 'Path is the Glusterfs volume path. More info:
+                          description: 'path is the Glusterfs volume path. More info:
                             https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
                           type: string
                         readOnly:
-                          description: 'ReadOnly here will force the Glusterfs volume
+                          description: 'readOnly here will force the Glusterfs volume
                             to be mounted with read-only permissions. Defaults to
                             false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod'
                           type: boolean
@@ -5077,7 +5218,7 @@
                       - path
                       type: object
                     hostPath:
-                      description: 'HostPath represents a pre-existing file or directory
+                      description: 'hostPath represents a pre-existing file or directory
                         on the host machine that is directly exposed to the container.
                         This is generally used for system agents or other privileged
                         things that are allowed to see the host machine. Most containers
@@ -5086,68 +5227,70 @@
                         mounts and who can/can not mount host directories as read/write.'
                       properties:
                         path:
-                          description: 'Path of the directory on the host. If the
+                          description: 'path of the directory on the host. If the
                             path is a symlink, it will follow the link to the real
                             path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath'
                           type: string
                         type:
-                          description: 'Type for HostPath Volume Defaults to "" More
+                          description: 'type for HostPath Volume Defaults to "" More
                             info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath'
                           type: string
                       required:
                       - path
                       type: object
                     iscsi:
-                      description: 'ISCSI represents an ISCSI Disk resource that is
+                      description: 'iscsi represents an ISCSI Disk resource that is
                         attached to a kubelet''s host machine and then exposed to
                         the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md'
                       properties:
                         chapAuthDiscovery:
-                          description: whether support iSCSI Discovery CHAP authentication
+                          description: chapAuthDiscovery defines whether support iSCSI
+                            Discovery CHAP authentication
                           type: boolean
                         chapAuthSession:
-                          description: whether support iSCSI Session CHAP authentication
+                          description: chapAuthSession defines whether support iSCSI
+                            Session CHAP authentication
                           type: boolean
                         fsType:
-                          description: 'Filesystem type of the volume that you want
-                            to mount. Tip: Ensure that the filesystem type is supported
-                            by the host operating system. Examples: "ext4", "xfs",
-                            "ntfs". Implicitly inferred to be "ext4" if unspecified.
-                            More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
+                          description: 'fsType is the filesystem type of the volume
+                            that you want to mount. Tip: Ensure that the filesystem
+                            type is supported by the host operating system. Examples:
+                            "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi
                             TODO: how do we prevent errors in the filesystem from
                             compromising the machine'
                           type: string
                         initiatorName:
-                          description: Custom iSCSI Initiator Name. If initiatorName
-                            is specified with iscsiInterface simultaneously, new iSCSI
-                            interface <target portal>:<volume name> will be created
-                            for the connection.
+                          description: initiatorName is the custom iSCSI Initiator
+                            Name. If initiatorName is specified with iscsiInterface
+                            simultaneously, new iSCSI interface <target portal>:<volume
+                            name> will be created for the connection.
                           type: string
                         iqn:
-                          description: Target iSCSI Qualified Name.
+                          description: iqn is the target iSCSI Qualified Name.
                           type: string
                         iscsiInterface:
-                          description: iSCSI Interface Name that uses an iSCSI transport.
-                            Defaults to 'default' (tcp).
+                          description: iscsiInterface is the interface Name that uses
+                            an iSCSI transport. Defaults to 'default' (tcp).
                           type: string
                         lun:
-                          description: iSCSI Target Lun number.
+                          description: lun represents iSCSI Target Lun number.
                           format: int32
                           type: integer
                         portals:
-                          description: iSCSI Target Portal List. The portal is either
-                            an IP or ip_addr:port if the port is other than default
-                            (typically TCP ports 860 and 3260).
+                          description: portals is the iSCSI Target Portal List. The
+                            portal is either an IP or ip_addr:port if the port is
+                            other than default (typically TCP ports 860 and 3260).
                           items:
                             type: string
                           type: array
                         readOnly:
-                          description: ReadOnly here will force the ReadOnly setting
+                          description: readOnly here will force the ReadOnly setting
                             in VolumeMounts. Defaults to false.
                           type: boolean
                         secretRef:
-                          description: CHAP Secret for iSCSI target and initiator
-                            authentication
+                          description: secretRef is the CHAP Secret for iSCSI target
+                            and initiator authentication
                           properties:
                             name:
                               description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
@@ -5155,9 +5298,9 @@
                               type: string
                           type: object
                         targetPortal:
-                          description: iSCSI Target Portal. The Portal is either an
-                            IP or ip_addr:port if the port is other than default (typically
-                            TCP ports 860 and 3260).
+                          description: targetPortal is iSCSI Target Portal. The Portal
+                            is either an IP or ip_addr:port if the port is other than
+                            default (typically TCP ports 860 and 3260).
                           type: string
                       required:
                       - iqn
@@ -5165,24 +5308,24 @@
                       - targetPortal
                       type: object
                     name:
-                      description: 'Volume''s name. Must be a DNS_LABEL and unique
+                      description: 'name of the volume. Must be a DNS_LABEL and unique
                         within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
                       type: string
                     nfs:
-                      description: 'NFS represents an NFS mount on the host that shares
+                      description: 'nfs represents an NFS mount on the host that shares
                         a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
                       properties:
                         path:
-                          description: 'Path that is exported by the NFS server. More
+                          description: 'path that is exported by the NFS server. More
                             info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
                           type: string
                         readOnly:
-                          description: 'ReadOnly here will force the NFS export to
+                          description: 'readOnly here will force the NFS export to
                             be mounted with read-only permissions. Defaults to false.
                             More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
                           type: boolean
                         server:
-                          description: 'Server is the hostname or IP address of the
+                          description: 'server is the hostname or IP address of the
                             NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs'
                           type: string
                       required:
@@ -5190,86 +5333,87 @@
                       - server
                       type: object
                     persistentVolumeClaim:
-                      description: 'PersistentVolumeClaimVolumeSource represents a
+                      description: 'persistentVolumeClaimVolumeSource represents a
                         reference to a PersistentVolumeClaim in the same namespace.
                         More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
                       properties:
                         claimName:
-                          description: 'ClaimName is the name of a PersistentVolumeClaim
+                          description: 'claimName is the name of a PersistentVolumeClaim
                             in the same namespace as the pod using this volume. More
                             info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
                           type: string
                         readOnly:
-                          description: Will force the ReadOnly setting in VolumeMounts.
-                            Default false.
+                          description: readOnly Will force the ReadOnly setting in
+                            VolumeMounts. Default false.
                           type: boolean
                       required:
                       - claimName
                       type: object
                     photonPersistentDisk:
-                      description: PhotonPersistentDisk represents a PhotonController
+                      description: photonPersistentDisk represents a PhotonController
                         persistent disk attached and mounted on kubelets host machine
                       properties:
                         fsType:
-                          description: Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Ex. "ext4",
-                            "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+                          description: fsType is the filesystem type to mount. Must
+                            be a filesystem type supported by the host operating system.
+                            Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified.
                           type: string
                         pdID:
-                          description: ID that identifies Photon Controller persistent
-                            disk
+                          description: pdID is the ID that identifies Photon Controller
+                            persistent disk
                           type: string
                       required:
                       - pdID
                       type: object
                     portworxVolume:
-                      description: PortworxVolume represents a portworx volume attached
+                      description: portworxVolume represents a portworx volume attached
                         and mounted on kubelets host machine
                       properties:
                         fsType:
-                          description: FSType represents the filesystem type to mount
+                          description: fSType represents the filesystem type to mount
                             Must be a filesystem type supported by the host operating
                             system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4"
                             if unspecified.
                           type: string
                         readOnly:
-                          description: Defaults to false (read/write). ReadOnly here
-                            will force the ReadOnly setting in VolumeMounts.
+                          description: readOnly defaults to false (read/write). ReadOnly
+                            here will force the ReadOnly setting in VolumeMounts.
                           type: boolean
                         volumeID:
-                          description: VolumeID uniquely identifies a Portworx volume
+                          description: volumeID uniquely identifies a Portworx volume
                           type: string
                       required:
                       - volumeID
                       type: object
                     projected:
-                      description: Items for all in one resources secrets, configmaps,
-                        and downward API
+                      description: projected items for all in one resources secrets,
+                        configmaps, and downward API
                       properties:
                         defaultMode:
-                          description: Mode bits used to set permissions on created
-                            files by default. Must be an octal value between 0000
-                            and 0777 or a decimal value between 0 and 511. YAML accepts
-                            both octal and decimal values, JSON requires decimal values
-                            for mode bits. Directories within the path are not affected
-                            by this setting. This might be in conflict with other
-                            options that affect the file mode, like fsGroup, and the
-                            result can be other mode bits set.
+                          description: defaultMode are the mode bits used to set permissions
+                            on created files by default. Must be an octal value between
+                            0000 and 0777 or a decimal value between 0 and 511. YAML
+                            accepts both octal and decimal values, JSON requires decimal
+                            values for mode bits. Directories within the path are
+                            not affected by this setting. This might be in conflict
+                            with other options that affect the file mode, like fsGroup,
+                            and the result can be other mode bits set.
                           format: int32
                           type: integer
                         sources:
-                          description: list of volume projections
+                          description: sources is the list of volume projections
                           items:
                             description: Projection that may be projected along with
                               other supported volume types
                             properties:
                               configMap:
-                                description: information about the configMap data
-                                  to project
+                                description: configMap information about the configMap
+                                  data to project
                                 properties:
                                   items:
-                                    description: If unspecified, each key-value pair
-                                      in the Data field of the referenced ConfigMap
+                                    description: items if unspecified, each key-value
+                                      pair in the Data field of the referenced ConfigMap
                                       will be projected into the volume as a file
                                       whose name is the key and content is the value.
                                       If specified, the listed keys will be projected
@@ -5284,27 +5428,28 @@
                                         a volume.
                                       properties:
                                         key:
-                                          description: The key to project.
+                                          description: key is the key to project.
                                           type: string
                                         mode:
-                                          description: 'Optional: mode bits used to
-                                            set permissions on this file. Must be
-                                            an octal value between 0000 and 0777 or
-                                            a decimal value between 0 and 511. YAML
-                                            accepts both octal and decimal values,
-                                            JSON requires decimal values for mode
-                                            bits. If not specified, the volume defaultMode
-                                            will be used. This might be in conflict
-                                            with other options that affect the file
-                                            mode, like fsGroup, and the result can
-                                            be other mode bits set.'
+                                          description: 'mode is Optional: mode bits
+                                            used to set permissions on this file.
+                                            Must be an octal value between 0000 and
+                                            0777 or a decimal value between 0 and
+                                            511. YAML accepts both octal and decimal
+                                            values, JSON requires decimal values for
+                                            mode bits. If not specified, the volume
+                                            defaultMode will be used. This might be
+                                            in conflict with other options that affect
+                                            the file mode, like fsGroup, and the result
+                                            can be other mode bits set.'
                                           format: int32
                                           type: integer
                                         path:
-                                          description: The relative path of the file
-                                            to map the key to. May not be an absolute
-                                            path. May not contain the path element
-                                            '..'. May not start with the string '..'.
+                                          description: path is the relative path of
+                                            the file to map the key to. May not be
+                                            an absolute path. May not contain the
+                                            path element '..'. May not start with
+                                            the string '..'.
                                           type: string
                                       required:
                                       - key
@@ -5318,13 +5463,13 @@
                                       uid?'
                                     type: string
                                   optional:
-                                    description: Specify whether the ConfigMap or
-                                      its keys must be defined
+                                    description: optional specify whether the ConfigMap
+                                      or its keys must be defined
                                     type: boolean
                                 type: object
                               downwardAPI:
-                                description: information about the downwardAPI data
-                                  to project
+                                description: downwardAPI information about the downwardAPI
+                                  data to project
                                 properties:
                                   items:
                                     description: Items is a list of DownwardAPIVolume
@@ -5405,15 +5550,15 @@
                                     type: array
                                 type: object
                               secret:
-                                description: information about the secret data to
-                                  project
+                                description: secret information about the secret data
+                                  to project
                                 properties:
                                   items:
-                                    description: If unspecified, each key-value pair
-                                      in the Data field of the referenced Secret will
-                                      be projected into the volume as a file whose
-                                      name is the key and content is the value. If
-                                      specified, the listed keys will be projected
+                                    description: items if unspecified, each key-value
+                                      pair in the Data field of the referenced Secret
+                                      will be projected into the volume as a file
+                                      whose name is the key and content is the value.
+                                      If specified, the listed keys will be projected
                                       into the specified paths, and unlisted keys
                                       will not be present. If a key is specified which
                                       is not present in the Secret, the volume setup
@@ -5425,27 +5570,28 @@
                                         a volume.
                                       properties:
                                         key:
-                                          description: The key to project.
+                                          description: key is the key to project.
                                           type: string
                                         mode:
-                                          description: 'Optional: mode bits used to
-                                            set permissions on this file. Must be
-                                            an octal value between 0000 and 0777 or
-                                            a decimal value between 0 and 511. YAML
-                                            accepts both octal and decimal values,
-                                            JSON requires decimal values for mode
-                                            bits. If not specified, the volume defaultMode
-                                            will be used. This might be in conflict
-                                            with other options that affect the file
-                                            mode, like fsGroup, and the result can
-                                            be other mode bits set.'
+                                          description: 'mode is Optional: mode bits
+                                            used to set permissions on this file.
+                                            Must be an octal value between 0000 and
+                                            0777 or a decimal value between 0 and
+                                            511. YAML accepts both octal and decimal
+                                            values, JSON requires decimal values for
+                                            mode bits. If not specified, the volume
+                                            defaultMode will be used. This might be
+                                            in conflict with other options that affect
+                                            the file mode, like fsGroup, and the result
+                                            can be other mode bits set.'
                                           format: int32
                                           type: integer
                                         path:
-                                          description: The relative path of the file
-                                            to map the key to. May not be an absolute
-                                            path. May not contain the path element
-                                            '..'. May not start with the string '..'.
+                                          description: path is the relative path of
+                                            the file to map the key to. May not be
+                                            an absolute path. May not contain the
+                                            path element '..'. May not start with
+                                            the string '..'.
                                           type: string
                                       required:
                                       - key
@@ -5459,16 +5605,16 @@
                                       uid?'
                                     type: string
                                   optional:
-                                    description: Specify whether the Secret or its
-                                      key must be defined
+                                    description: optional field specify whether the
+                                      Secret or its key must be defined
                                     type: boolean
                                 type: object
                               serviceAccountToken:
-                                description: information about the serviceAccountToken
-                                  data to project
+                                description: serviceAccountToken is information about
+                                  the serviceAccountToken data to project
                                 properties:
                                   audience:
-                                    description: Audience is the intended audience
+                                    description: audience is the intended audience
                                       of the token. A recipient of a token must identify
                                       itself with an identifier specified in the audience
                                       of the token, and otherwise should reject the
@@ -5476,7 +5622,7 @@
                                       of the apiserver.
                                     type: string
                                   expirationSeconds:
-                                    description: ExpirationSeconds is the requested
+                                    description: expirationSeconds is the requested
                                       duration of validity of the service account
                                       token. As the token approaches expiration, the
                                       kubelet volume plugin will proactively rotate
@@ -5488,7 +5634,7 @@
                                     format: int64
                                     type: integer
                                   path:
-                                    description: Path is the path relative to the
+                                    description: path is the path relative to the
                                       mount point of the file to project the token
                                       into.
                                     type: string
@@ -5499,35 +5645,35 @@
                           type: array
                       type: object
                     quobyte:
-                      description: Quobyte represents a Quobyte mount on the host
+                      description: quobyte represents a Quobyte mount on the host
                         that shares a pod's lifetime
                       properties:
                         group:
-                          description: Group to map volume access to Default is no
+                          description: group to map volume access to Default is no
                             group
                           type: string
                         readOnly:
-                          description: ReadOnly here will force the Quobyte volume
+                          description: readOnly here will force the Quobyte volume
                             to be mounted with read-only permissions. Defaults to
                             false.
                           type: boolean
                         registry:
-                          description: Registry represents a single or multiple Quobyte
+                          description: registry represents a single or multiple Quobyte
                             Registry services specified as a string as host:port pair
                             (multiple entries are separated with commas) which acts
                             as the central registry for volumes
                           type: string
                         tenant:
-                          description: Tenant owning the given Quobyte volume in the
+                          description: tenant owning the given Quobyte volume in the
                             Backend Used with dynamically provisioned Quobyte volumes,
                             value is set by the plugin
                           type: string
                         user:
-                          description: User to map volume access to Defaults to serivceaccount
+                          description: user to map volume access to Defaults to serivceaccount
                             user
                           type: string
                         volume:
-                          description: Volume is a string that references an already
+                          description: volume is a string that references an already
                             created Quobyte volume by name.
                           type: string
                       required:
@@ -5535,41 +5681,42 @@
                       - volume
                       type: object
                     rbd:
-                      description: 'RBD represents a Rados Block Device mount on the
+                      description: 'rbd represents a Rados Block Device mount on the
                         host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md'
                       properties:
                         fsType:
-                          description: 'Filesystem type of the volume that you want
-                            to mount. Tip: Ensure that the filesystem type is supported
-                            by the host operating system. Examples: "ext4", "xfs",
-                            "ntfs". Implicitly inferred to be "ext4" if unspecified.
-                            More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
+                          description: 'fsType is the filesystem type of the volume
+                            that you want to mount. Tip: Ensure that the filesystem
+                            type is supported by the host operating system. Examples:
+                            "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd
                             TODO: how do we prevent errors in the filesystem from
                             compromising the machine'
                           type: string
                         image:
-                          description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+                          description: 'image is the rados image name. More info:
+                            https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
                           type: string
                         keyring:
-                          description: 'Keyring is the path to key ring for RBDUser.
+                          description: 'keyring is the path to key ring for RBDUser.
                             Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
                           type: string
                         monitors:
-                          description: 'A collection of Ceph monitors. More info:
-                            https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+                          description: 'monitors is a collection of Ceph monitors.
+                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
                           items:
                             type: string
                           type: array
                         pool:
-                          description: 'The rados pool name. Default is rbd. More
-                            info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+                          description: 'pool is the rados pool name. Default is rbd.
+                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
                           type: string
                         readOnly:
-                          description: 'ReadOnly here will force the ReadOnly setting
+                          description: 'readOnly here will force the ReadOnly setting
                             in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
                           type: boolean
                         secretRef:
-                          description: 'SecretRef is name of the authentication secret
+                          description: 'secretRef is name of the authentication secret
                             for RBDUser. If provided overrides keyring. Default is
                             nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
                           properties:
@@ -5579,35 +5726,36 @@
                               type: string
                           type: object
                         user:
-                          description: 'The rados user name. Default is admin. More
-                            info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
+                          description: 'user is the rados user name. Default is admin.
+                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it'
                           type: string
                       required:
                       - image
                       - monitors
                       type: object
                     scaleIO:
-                      description: ScaleIO represents a ScaleIO persistent volume
+                      description: scaleIO represents a ScaleIO persistent volume
                         attached and mounted on Kubernetes nodes.
                       properties:
                         fsType:
-                          description: Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Ex. "ext4",
-                            "xfs", "ntfs". Default is "xfs".
+                          description: fsType is the filesystem type to mount. Must
+                            be a filesystem type supported by the host operating system.
+                            Ex. "ext4", "xfs", "ntfs". Default is "xfs".
                           type: string
                         gateway:
-                          description: The host address of the ScaleIO API Gateway.
+                          description: gateway is the host address of the ScaleIO
+                            API Gateway.
                           type: string
                         protectionDomain:
-                          description: The name of the ScaleIO Protection Domain for
-                            the configured storage.
+                          description: protectionDomain is the name of the ScaleIO
+                            Protection Domain for the configured storage.
                           type: string
                         readOnly:
-                          description: Defaults to false (read/write). ReadOnly here
-                            will force the ReadOnly setting in VolumeMounts.
+                          description: readOnly Defaults to false (read/write). ReadOnly
+                            here will force the ReadOnly setting in VolumeMounts.
                           type: boolean
                         secretRef:
-                          description: SecretRef references to the secret for ScaleIO
+                          description: secretRef references to the secret for ScaleIO
                             user and other sensitive information. If this is not provided,
                             Login operation will fail.
                           properties:
@@ -5617,25 +5765,26 @@
                               type: string
                           type: object
                         sslEnabled:
-                          description: Flag to enable/disable SSL communication with
-                            Gateway, default false
+                          description: sslEnabled Flag enable/disable SSL communication
+                            with Gateway, default false
                           type: boolean
                         storageMode:
-                          description: Indicates whether the storage for a volume
-                            should be ThickProvisioned or ThinProvisioned. Default
-                            is ThinProvisioned.
+                          description: storageMode indicates whether the storage for
+                            a volume should be ThickProvisioned or ThinProvisioned.
+                            Default is ThinProvisioned.
                           type: string
                         storagePool:
-                          description: The ScaleIO Storage Pool associated with the
-                            protection domain.
+                          description: storagePool is the ScaleIO Storage Pool associated
+                            with the protection domain.
                           type: string
                         system:
-                          description: The name of the storage system as configured
-                            in ScaleIO.
+                          description: system is the name of the storage system as
+                            configured in ScaleIO.
                           type: string
                         volumeName:
-                          description: The name of a volume already created in the
-                            ScaleIO system that is associated with this volume source.
+                          description: volumeName is the name of a volume already
+                            created in the ScaleIO system that is associated with
+                            this volume source.
                           type: string
                       required:
                       - gateway
@@ -5643,24 +5792,24 @@
                       - system
                       type: object
                     secret:
-                      description: 'Secret represents a secret that should populate
+                      description: 'secret represents a secret that should populate
                         this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret'
                       properties:
                         defaultMode:
-                          description: 'Optional: mode bits used to set permissions
-                            on created files by default. Must be an octal value between
-                            0000 and 0777 or a decimal value between 0 and 511. YAML
-                            accepts both octal and decimal values, JSON requires decimal
-                            values for mode bits. Defaults to 0644. Directories within
-                            the path are not affected by this setting. This might
-                            be in conflict with other options that affect the file
-                            mode, like fsGroup, and the result can be other mode bits
-                            set.'
+                          description: 'defaultMode is Optional: mode bits used to
+                            set permissions on created files by default. Must be an
+                            octal value between 0000 and 0777 or a decimal value between
+                            0 and 511. YAML accepts both octal and decimal values,
+                            JSON requires decimal values for mode bits. Defaults to
+                            0644. Directories within the path are not affected by
+                            this setting. This might be in conflict with other options
+                            that affect the file mode, like fsGroup, and the result
+                            can be other mode bits set.'
                           format: int32
                           type: integer
                         items:
-                          description: If unspecified, each key-value pair in the
-                            Data field of the referenced Secret will be projected
+                          description: items If unspecified, each key-value pair in
+                            the Data field of the referenced Secret will be projected
                             into the volume as a file whose name is the key and content
                             is the value. If specified, the listed keys will be projected
                             into the specified paths, and unlisted keys will not be
@@ -5672,25 +5821,25 @@
                             description: Maps a string key to a path within a volume.
                             properties:
                               key:
-                                description: The key to project.
+                                description: key is the key to project.
                                 type: string
                               mode:
-                                description: 'Optional: mode bits used to set permissions
-                                  on this file. Must be an octal value between 0000
-                                  and 0777 or a decimal value between 0 and 511. YAML
-                                  accepts both octal and decimal values, JSON requires
-                                  decimal values for mode bits. If not specified,
-                                  the volume defaultMode will be used. This might
-                                  be in conflict with other options that affect the
-                                  file mode, like fsGroup, and the result can be other
-                                  mode bits set.'
+                                description: 'mode is Optional: mode bits used to
+                                  set permissions on this file. Must be an octal value
+                                  between 0000 and 0777 or a decimal value between
+                                  0 and 511. YAML accepts both octal and decimal values,
+                                  JSON requires decimal values for mode bits. If not
+                                  specified, the volume defaultMode will be used.
+                                  This might be in conflict with other options that
+                                  affect the file mode, like fsGroup, and the result
+                                  can be other mode bits set.'
                                 format: int32
                                 type: integer
                               path:
-                                description: The relative path of the file to map
-                                  the key to. May not be an absolute path. May not
-                                  contain the path element '..'. May not start with
-                                  the string '..'.
+                                description: path is the relative path of the file
+                                  to map the key to. May not be an absolute path.
+                                  May not contain the path element '..'. May not start
+                                  with the string '..'.
                                 type: string
                             required:
                             - key
@@ -5698,29 +5847,30 @@
                             type: object
                           type: array
                         optional:
-                          description: Specify whether the Secret or its keys must
-                            be defined
+                          description: optional field specify whether the Secret or
+                            its keys must be defined
                           type: boolean
                         secretName:
-                          description: 'Name of the secret in the pod''s namespace
-                            to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret'
+                          description: 'secretName is the name of the secret in the
+                            pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret'
                           type: string
                       type: object
                     storageos:
-                      description: StorageOS represents a StorageOS volume attached
+                      description: storageOS represents a StorageOS volume attached
                         and mounted on Kubernetes nodes.
                       properties:
                         fsType:
-                          description: Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Ex. "ext4",
-                            "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+                          description: fsType is the filesystem type to mount. Must
+                            be a filesystem type supported by the host operating system.
+                            Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified.
                           type: string
                         readOnly:
-                          description: Defaults to false (read/write). ReadOnly here
-                            will force the ReadOnly setting in VolumeMounts.
+                          description: readOnly defaults to false (read/write). ReadOnly
+                            here will force the ReadOnly setting in VolumeMounts.
                           type: boolean
                         secretRef:
-                          description: SecretRef specifies the secret to use for obtaining
+                          description: secretRef specifies the secret to use for obtaining
                             the StorageOS API credentials.  If not specified, default
                             values will be attempted.
                           properties:
@@ -5730,12 +5880,12 @@
                               type: string
                           type: object
                         volumeName:
-                          description: VolumeName is the human-readable name of the
+                          description: volumeName is the human-readable name of the
                             StorageOS volume.  Volume names are only unique within
                             a namespace.
                           type: string
                         volumeNamespace:
-                          description: VolumeNamespace specifies the scope of the
+                          description: volumeNamespace specifies the scope of the
                             volume within StorageOS.  If no namespace is specified
                             then the Pod's namespace will be used.  This allows the
                             Kubernetes name scoping to be mirrored within StorageOS
@@ -5746,24 +5896,26 @@
                           type: string
                       type: object
                     vsphereVolume:
-                      description: VsphereVolume represents a vSphere volume attached
+                      description: vsphereVolume represents a vSphere volume attached
                         and mounted on kubelets host machine
                       properties:
                         fsType:
-                          description: Filesystem type to mount. Must be a filesystem
-                            type supported by the host operating system. Ex. "ext4",
-                            "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
+                          description: fsType is filesystem type to mount. Must be
+                            a filesystem type supported by the host operating system.
+                            Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4"
+                            if unspecified.
                           type: string
                         storagePolicyID:
-                          description: Storage Policy Based Management (SPBM) profile
-                            ID associated with the StoragePolicyName.
+                          description: storagePolicyID is the storage Policy Based
+                            Management (SPBM) profile ID associated with the StoragePolicyName.
                           type: string
                         storagePolicyName:
-                          description: Storage Policy Based Management (SPBM) profile
-                            name.
+                          description: storagePolicyName is the storage Policy Based
+                            Management (SPBM) profile name.
                           type: string
                         volumePath:
-                          description: Path that identifies vSphere volume vmdk
+                          description: volumePath is the path that identifies vSphere
+                            volume vmdk
                           type: string
                       required:
                       - volumePath
@@ -5849,9 +6001,3 @@
     storage: true
     subresources:
       status: {}
-status:
-  acceptedNames:
-    kind: ""
-    plural: ""
-  conditions: []
-  storedVersions: []
diff --git a/controllers/controller_utils_test.go b/controllers/controller_utils_test.go
index 10fa31c..b7349cd 100644
--- a/controllers/controller_utils_test.go
+++ b/controllers/controller_utils_test.go
@@ -20,12 +20,12 @@
 import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	policyv1 "k8s.io/api/policy/v1"
 	"regexp"
 
 	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
 	"github.com/apache/solr-operator/controllers/util"
-	zk_api "github.com/apache/solr-operator/controllers/zk_api"
 	"golang.org/x/net/context"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -702,7 +702,7 @@
 	cleanupObjects := []client.Object{
 		// Solr Operator CRDs, modify this list whenever CRDs are added/deleted
 		&solrv1beta1.SolrCloud{}, &solrv1beta1.SolrBackup{}, &solrv1beta1.SolrPrometheusExporter{},
-		&zk_api.ZookeeperCluster{},
+		&zkApi.ZookeeperCluster{},
 
 		// All dependent Kubernetes types, in order of dependence (deployment then replicaSet then pod)
 		&corev1.ConfigMap{}, &netv1.Ingress{},
@@ -1005,13 +1005,13 @@
 	testIngressClass = "test-ingress-class"
 	testSolrZKOpts   = "-Dsolr.zk.opts=this"
 	testSolrOpts     = "-Dsolr.opts=this"
-	testZkProbes     = zk_api.Probes{
-		ReadinessProbe: &zk_api.Probe{
+	testZkProbes     = zkApi.Probes{
+		ReadinessProbe: &zkApi.Probe{
 			PeriodSeconds:    3,
 			SuccessThreshold: 5,
 			TimeoutSeconds:   10,
 		},
-		LivenessProbe: &zk_api.Probe{
+		LivenessProbe: &zkApi.Probe{
 			InitialDelaySeconds: 6,
 			PeriodSeconds:       4,
 			FailureThreshold:    0,
diff --git a/controllers/solrcloud_controller.go b/controllers/solrcloud_controller.go
index 8b02e99..d0e3363 100644
--- a/controllers/solrcloud_controller.go
+++ b/controllers/solrcloud_controller.go
@@ -30,8 +30,8 @@
 
 	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
 	"github.com/apache/solr-operator/controllers/util"
-	"github.com/apache/solr-operator/controllers/zk_api"
 	"github.com/go-logr/logr"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	netv1 "k8s.io/api/networking/v1"
@@ -765,7 +765,7 @@
 
 		// Check if the ZookeeperCluster already exists
 		zkLogger := logger.WithValues("zookeeperCluster", zkCluster.Name)
-		foundZkCluster := &zk_api.ZookeeperCluster{}
+		foundZkCluster := &zkApi.ZookeeperCluster{}
 		err := r.Get(ctx, types.NamespacedName{Name: zkCluster.Name, Namespace: zkCluster.Namespace}, foundZkCluster)
 		if err != nil && errors.IsNotFound(err) {
 			zkLogger.Info("Creating Zookeeer Cluster")
@@ -990,7 +990,7 @@
 	}
 
 	if useZkCRD {
-		ctrlBuilder = ctrlBuilder.Owns(&zk_api.ZookeeperCluster{})
+		ctrlBuilder = ctrlBuilder.Owns(&zkApi.ZookeeperCluster{})
 	}
 
 	return ctrlBuilder.Complete(r)
diff --git a/controllers/solrcloud_controller_zk_test.go b/controllers/solrcloud_controller_zk_test.go
index ad39a4c..57024bb 100644
--- a/controllers/solrcloud_controller_zk_test.go
+++ b/controllers/solrcloud_controller_zk_test.go
@@ -24,9 +24,9 @@
 
 	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
 	"github.com/apache/solr-operator/controllers/util"
-	zk_crd "github.com/apache/solr-operator/controllers/zk_api"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -577,12 +577,12 @@
 	})
 })
 
-func expectZookeeperCluster(ctx context.Context, parentResource client.Object, zkName string, additionalOffset ...int) *zk_crd.ZookeeperCluster {
+func expectZookeeperCluster(ctx context.Context, parentResource client.Object, zkName string, additionalOffset ...int) *zkApi.ZookeeperCluster {
 	return expectZookeeperClusterWithChecks(ctx, parentResource, zkName, nil, resolveOffset(additionalOffset))
 }
 
-func expectZookeeperClusterWithChecks(ctx context.Context, parentResource client.Object, zkName string, additionalChecks func(Gomega, *zk_crd.ZookeeperCluster), additionalOffset ...int) *zk_crd.ZookeeperCluster {
-	found := &zk_crd.ZookeeperCluster{}
+func expectZookeeperClusterWithChecks(ctx context.Context, parentResource client.Object, zkName string, additionalChecks func(Gomega, *zkApi.ZookeeperCluster), additionalOffset ...int) *zkApi.ZookeeperCluster {
+	found := &zkApi.ZookeeperCluster{}
 	EventuallyWithOffset(resolveOffset(additionalOffset), func(g Gomega) {
 		g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, zkName), found)).To(Succeed(), "Expected ZookeeperCluster does not exist")
 		if additionalChecks != nil {
@@ -594,7 +594,7 @@
 	ExpectWithOffset(resolveOffset(additionalOffset), k8sClient.Delete(ctx, found)).To(Succeed())
 	Eventually(
 		func(g Gomega) types.UID {
-			newResource := &zk_crd.ZookeeperCluster{}
+			newResource := &zkApi.ZookeeperCluster{}
 			g.Expect(k8sClient.Get(ctx, resourceKey(parentResource, zkName), newResource)).To(Succeed(), "ZookeeperCluster not recreated after deletion")
 			return newResource.UID
 		}).Should(And(Not(BeEmpty()), Not(Equal(found.UID))), "New ZookeeperCluster, with new UID, not created.")
@@ -603,6 +603,6 @@
 
 func expectNoZookeeperCluster(ctx context.Context, parentResource client.Object, zkName string, additionalOffset ...int) {
 	ConsistentlyWithOffset(resolveOffset(additionalOffset), func() error {
-		return k8sClient.Get(ctx, resourceKey(parentResource, zkName), &zk_crd.ZookeeperCluster{})
+		return k8sClient.Get(ctx, resourceKey(parentResource, zkName), &zkApi.ZookeeperCluster{})
 	}).Should(MatchError("zookeeperclusters.zookeeper.pravega.io \""+zkName+"\" not found"), "ZookeeperCluster exists when it should not")
 }
diff --git a/controllers/suite_test.go b/controllers/suite_test.go
index f17365f..804eb61 100644
--- a/controllers/suite_test.go
+++ b/controllers/suite_test.go
@@ -19,8 +19,8 @@
 
 import (
 	"context"
-	zk_api "github.com/apache/solr-operator/controllers/zk_api"
 	"github.com/go-logr/logr"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	"path/filepath"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"testing"
@@ -88,7 +88,7 @@
 	Expect(cfg).NotTo(BeNil())
 
 	err = solrv1beta1.AddToScheme(scheme.Scheme)
-	err = zk_api.AddToScheme(scheme.Scheme)
+	err = zkApi.AddToScheme(scheme.Scheme)
 	Expect(err).NotTo(HaveOccurred())
 
 	//+kubebuilder:scaffold:scheme
diff --git a/controllers/util/zk_util.go b/controllers/util/zk_util.go
index 1365683..b347737 100644
--- a/controllers/util/zk_util.go
+++ b/controllers/util/zk_util.go
@@ -21,8 +21,8 @@
 	"strings"
 
 	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
-	"github.com/apache/solr-operator/controllers/zk_api"
 	"github.com/go-logr/logr"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -30,18 +30,18 @@
 // GenerateZookeeperCluster returns a new ZookeeperCluster pointer generated for the SolrCloud instance
 // object: SolrCloud instance
 // zkSpec: the spec of the ZookeeperCluster to generate
-func GenerateZookeeperCluster(solrCloud *solrv1beta1.SolrCloud, zkSpec *solrv1beta1.ZookeeperSpec) *zk_api.ZookeeperCluster {
+func GenerateZookeeperCluster(solrCloud *solrv1beta1.SolrCloud, zkSpec *solrv1beta1.ZookeeperSpec) *zkApi.ZookeeperCluster {
 	labels := solrCloud.SharedLabelsWith(solrCloud.GetLabels())
 	labels["technology"] = solrv1beta1.ZookeeperTechnologyLabel
 
-	zkCluster := &zk_api.ZookeeperCluster{
+	zkCluster := &zkApi.ZookeeperCluster{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      solrCloud.ProvidedZookeeperName(),
 			Namespace: solrCloud.GetNamespace(),
 			Labels:    labels,
 		},
-		Spec: zk_api.ZookeeperClusterSpec{
-			Image: zk_api.ContainerImage{
+		Spec: zkApi.ZookeeperClusterSpec{
+			Image: zkApi.ContainerImage{
 				Repository: zkSpec.Image.Repository,
 				Tag:        zkSpec.Image.Tag,
 				PullPolicy: zkSpec.Image.PullPolicy,
@@ -62,7 +62,7 @@
 					ContainerPort: 3888,
 				},
 			},
-			Conf: zk_api.ZookeeperConfig(zkSpec.Config),
+			Conf: zkApi.ZookeeperConfig(zkSpec.Config),
 		},
 	}
 
@@ -84,13 +84,13 @@
 
 	// Set the persistence/ephemeral options if necessary
 	if zkSpec.Persistence != nil && zkCluster.Spec.StorageType == "persistence" {
-		zkCluster.Spec.Persistence = &zk_api.Persistence{
-			VolumeReclaimPolicy:       zk_api.VolumeReclaimPolicy(zkSpec.Persistence.VolumeReclaimPolicy),
+		zkCluster.Spec.Persistence = &zkApi.Persistence{
+			VolumeReclaimPolicy:       zkApi.VolumeReclaimPolicy(zkSpec.Persistence.VolumeReclaimPolicy),
 			PersistentVolumeClaimSpec: zkSpec.Persistence.PersistentVolumeClaimSpec,
 			Annotations:               zkSpec.Persistence.Annotations,
 		}
 	} else if zkSpec.Ephemeral != nil && zkCluster.Spec.StorageType == "ephemeral" {
-		zkCluster.Spec.Ephemeral = &zk_api.Ephemeral{
+		zkCluster.Spec.Ephemeral = &zkApi.Ephemeral{
 			EmptyDirVolumeSource: zkSpec.Ephemeral.EmptyDirVolumeSource,
 		}
 	}
@@ -178,7 +178,7 @@
 
 // CopyZookeeperClusterFields copies the owned fields from one ZookeeperCluster to another
 // Returns true if the fields copied from don't match to.
-func CopyZookeeperClusterFields(from, to *zk_api.ZookeeperCluster, logger logr.Logger) bool {
+func CopyZookeeperClusterFields(from, to *zkApi.ZookeeperCluster, logger logr.Logger) bool {
 	logger = logger.WithValues("kind", "zookeeperCluster")
 	requireUpdate := CopyLabelsAndAnnotations(&from.ObjectMeta, &to.ObjectMeta, logger)
 
diff --git a/controllers/util/zk_util_test.go b/controllers/util/zk_util_test.go
index 5ac6d96..96876d1 100644
--- a/controllers/util/zk_util_test.go
+++ b/controllers/util/zk_util_test.go
@@ -19,7 +19,7 @@
 
 import (
 	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
-	"github.com/apache/solr-operator/controllers/zk_api"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 
 	"github.com/stretchr/testify/assert"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -37,7 +37,7 @@
 	}
 	zkSpec.WithDefaults()
 
-	var zkCluster *zk_api.ZookeeperCluster
+	var zkCluster *zkApi.ZookeeperCluster
 
 	// Solr uses nothing (defaults to ephemeral)
 	zkCluster = GenerateZookeeperCluster(solrCloud, zkSpec)
diff --git a/controllers/zk_api/groupversion_info.go b/controllers/zk_api/groupversion_info.go
deleted file mode 100644
index 71e0ce8..0000000
--- a/controllers/zk_api/groupversion_info.go
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 v1beta1 contains API Schema definitions for the zookeeper.pravega.io v1beta1 API group
-// +kubebuilder:object:generate=true
-// +groupName=zookeeper.pravega.io
-package zk_api
-
-import (
-	"k8s.io/apimachinery/pkg/runtime/schema"
-	"sigs.k8s.io/controller-runtime/pkg/scheme"
-)
-
-var (
-	// GroupVersion is group version used to register these objects
-	GroupVersion = schema.GroupVersion{Group: "zookeeper.pravega.io", Version: "v1beta1"}
-
-	// SchemeBuilder is used to add go types to the GroupVersionKind scheme
-	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
-
-	// AddToScheme adds the types in this group-version to the given scheme.
-	AddToScheme = SchemeBuilder.AddToScheme
-)
diff --git a/controllers/zk_api/zkcluster.go b/controllers/zk_api/zkcluster.go
deleted file mode 100644
index cf4820c..0000000
--- a/controllers/zk_api/zkcluster.go
+++ /dev/null
@@ -1,797 +0,0 @@
-/**
- * Copyright (c) 2018 Dell Inc., or its subsidiaries. All Rights Reserved.
- *
- * 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
- */
-
-package zk_api
-
-import (
-	"fmt"
-	"strings"
-
-	v1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/api/resource"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-const (
-	// DefaultZkContainerRepository is the default docker repo for the zookeeper
-	// container
-	DefaultZkContainerRepository = "pravega/zookeeper"
-
-	// DefaultZkContainerVersion is the default tag used for for the zookeeper
-	// container
-	DefaultZkContainerVersion = "0.2.14"
-
-	// DefaultZkContainerPolicy is the default container pull policy used
-	DefaultZkContainerPolicy = v1.PullIfNotPresent
-
-	// DefaultTerminationGracePeriod is the default time given before the
-	// container is stopped. This gives clients time to disconnect from a
-	// specific node gracefully.
-	DefaultTerminationGracePeriod = 30
-
-	// DefaultZookeeperCacheVolumeSize is the default volume size for the
-	// Zookeeper cache volume
-	DefaultZookeeperCacheVolumeSize = "20Gi"
-
-	// DefaultReadinessProbeInitialDelaySeconds is the default initial delay (in seconds)
-	// for the readiness probe
-	DefaultReadinessProbeInitialDelaySeconds = 10
-
-	// DefaultReadinessProbePeriodSeconds is the default probe period (in seconds)
-	// for the readiness probe
-	DefaultReadinessProbePeriodSeconds = 10
-
-	// DefaultReadinessProbeFailureThreshold is the default probe failure threshold
-	// for the readiness probe
-	DefaultReadinessProbeFailureThreshold = 3
-
-	// DefaultReadinessProbeSuccessThreshold is the default probe success threshold
-	// for the readiness probe
-	DefaultReadinessProbeSuccessThreshold = 1
-
-	// DefaultReadinessProbeTimeoutSeconds is the default probe timeout (in seconds)
-	// for the readiness probe
-	DefaultReadinessProbeTimeoutSeconds = 10
-
-	// DefaultLivenessProbeInitialDelaySeconds is the default initial delay (in seconds)
-	// for the liveness probe
-	DefaultLivenessProbeInitialDelaySeconds = 10
-
-	// DefaultLivenessProbePeriodSeconds is the default probe period (in seconds)
-	// for the liveness probe
-	DefaultLivenessProbePeriodSeconds = 10
-
-	// DefaultLivenessProbeFailureThreshold is the default probe failure threshold
-	// for the liveness probe
-	DefaultLivenessProbeFailureThreshold = 3
-
-	// DefaultLivenessProbeTimeoutSeconds is the default probe timeout (in seconds)
-	// for the liveness probe
-	DefaultLivenessProbeTimeoutSeconds = 10
-)
-
-// ZookeeperClusterSpec defines the desired state of ZookeeperCluster
-type ZookeeperClusterSpec struct {
-	// Image is the  container image. default is zookeeper:0.2.10
-	Image ContainerImage `json:"image,omitempty"`
-
-	// Labels specifies the labels to attach to pods the operator creates for
-	// the zookeeper cluster.
-	Labels map[string]string `json:"labels,omitempty"`
-
-	// Replicas is the expected size of the zookeeper cluster.
-	// The pravega-operator will eventually make the size of the running cluster
-	// equal to the expected size.
-	//
-	// The valid range of size is from 1 to 7.
-	// +kubebuilder:validation:Minimum=1
-	Replicas int32 `json:"replicas,omitempty"`
-
-	Ports []v1.ContainerPort `json:"ports,omitempty"`
-
-	// Pod defines the policy to create pod for the zookeeper cluster.
-	// Updating the Pod does not take effect on any existing pods.
-	Pod PodPolicy `json:"pod,omitempty"`
-
-	// AdminServerService defines the policy to create AdminServer Service
-	// for the zookeeper cluster.
-	AdminServerService AdminServerServicePolicy `json:"adminServerService,omitempty"`
-
-	// ClientService defines the policy to create client Service
-	// for the zookeeper cluster.
-	ClientService ClientServicePolicy `json:"clientService,omitempty"`
-
-	// TriggerRollingRestart if set to true will instruct operator to restart all
-	// the pods in the zookeeper cluster, after which this value will be set to false
-	TriggerRollingRestart bool `json:"triggerRollingRestart,omitempty"`
-
-	// HeadlessService defines the policy to create headless Service
-	// for the zookeeper cluster.
-	HeadlessService HeadlessServicePolicy `json:"headlessService,omitempty"`
-
-	//StorageType is used to tell which type of storage we will be using
-	//It can take either Ephemeral or persistence
-	//Default StorageType is Persistence storage
-	StorageType string `json:"storageType,omitempty"`
-
-	// Persistence is the configuration for zookeeper persistent layer.
-	// PersistentVolumeClaimSpec and VolumeReclaimPolicy can be specified in here.
-	Persistence *Persistence `json:"persistence,omitempty"`
-
-	// Ephemeral is the configuration which helps create ephemeral storage
-	// At anypoint only one of Persistence or Ephemeral should be present in the manifest
-	Ephemeral *Ephemeral `json:"ephemeral,omitempty"`
-
-	// Conf is the zookeeper configuration, which will be used to generate the
-	// static zookeeper configuration. If no configuration is provided required
-	// default values will be provided, and optional values will be excluded.
-	Conf ZookeeperConfig `json:"config,omitempty"`
-
-	// External host name appended for dns annotation
-	DomainName string `json:"domainName,omitempty"`
-
-	// Domain of the kubernetes cluster, defaults to cluster.local
-	KubernetesClusterDomain string `json:"kubernetesClusterDomain,omitempty"`
-
-	// Containers defines to support multi containers
-	Containers []v1.Container `json:"containers,omitempty"`
-
-	// Init containers to support initialization
-	InitContainers []v1.Container `json:"initContainers,omitempty"`
-
-	// Volumes defines to support customized volumes
-	Volumes []v1.Volume `json:"volumes,omitempty"`
-
-	// VolumeMounts defines to support customized volumeMounts
-	VolumeMounts []v1.VolumeMount `json:"volumeMounts,omitempty"`
-
-	// Probes specifies the timeout values for the Readiness and Liveness Probes
-	// for the zookeeper pods.
-	// +optional
-	Probes *Probes `json:"probes,omitempty"`
-
-	// MaxUnavailableReplicas defines the
-	// MaxUnavailable Replicas in pdb.
-	// Default is 1.
-	MaxUnavailableReplicas int32 `json:"maxUnavailableReplicas,omitempty"`
-}
-
-type Probes struct {
-	// +optional
-	ReadinessProbe *Probe `json:"readinessProbe,omitempty"`
-	// +optional
-	LivenessProbe *Probe `json:"livenessProbe,omitempty"`
-}
-
-func (s *ZookeeperClusterSpec) withDefaults(z *ZookeeperCluster) (changed bool) {
-	changed = s.Image.withDefaults()
-	if s.Conf.withDefaults() {
-		changed = true
-	}
-	if s.Replicas == 0 {
-		s.Replicas = 3
-		changed = true
-	}
-	if s.Probes == nil {
-		changed = true
-		s.Probes = &Probes{}
-	}
-	if s.Probes.withDefaults() {
-		changed = true
-	}
-
-	if s.Ports == nil {
-		s.Ports = []v1.ContainerPort{
-			{
-				Name:          "client",
-				ContainerPort: 2181,
-			},
-			{
-				Name:          "quorum",
-				ContainerPort: 2888,
-			},
-			{
-				Name:          "leader-election",
-				ContainerPort: 3888,
-			},
-			{
-				Name:          "metrics",
-				ContainerPort: 7000,
-			},
-			{
-				Name:          "admin-server",
-				ContainerPort: 8080,
-			},
-		}
-		changed = true
-	} else {
-		var (
-			foundClient, foundQuorum, foundLeader, foundMetrics, foundAdmin bool
-		)
-		for i := 0; i < len(s.Ports); i++ {
-			if s.Ports[i].Name == "client" {
-				foundClient = true
-			} else if s.Ports[i].Name == "quorum" {
-				foundQuorum = true
-			} else if s.Ports[i].Name == "leader-election" {
-				foundLeader = true
-			} else if s.Ports[i].Name == "metrics" {
-				foundMetrics = true
-			} else if s.Ports[i].Name == "admin-server" {
-				foundAdmin = true
-			}
-		}
-		if !foundClient {
-			ports := v1.ContainerPort{Name: "client", ContainerPort: 2181}
-			s.Ports = append(s.Ports, ports)
-			changed = true
-		}
-		if !foundQuorum {
-			ports := v1.ContainerPort{Name: "quorum", ContainerPort: 2888}
-			s.Ports = append(s.Ports, ports)
-			changed = true
-		}
-		if !foundLeader {
-			ports := v1.ContainerPort{Name: "leader-election", ContainerPort: 3888}
-			s.Ports = append(s.Ports, ports)
-			changed = true
-		}
-		if !foundMetrics {
-			ports := v1.ContainerPort{Name: "metrics", ContainerPort: 7000}
-			s.Ports = append(s.Ports, ports)
-			changed = true
-		}
-		if !foundAdmin {
-			ports := v1.ContainerPort{Name: "admin-server", ContainerPort: 8080}
-			s.Ports = append(s.Ports, ports)
-			changed = true
-		}
-	}
-
-	if z.Spec.Labels == nil {
-		z.Spec.Labels = map[string]string{}
-		changed = true
-	}
-	if _, ok := z.Spec.Labels["app"]; !ok {
-		z.Spec.Labels["app"] = z.GetName()
-		changed = true
-	}
-	if _, ok := z.Spec.Labels["release"]; !ok {
-		z.Spec.Labels["release"] = z.GetName()
-		changed = true
-	}
-	if s.Pod.withDefaults(z) {
-		changed = true
-	}
-	if strings.EqualFold(s.StorageType, "ephemeral") {
-		if s.Ephemeral == nil {
-			s.Ephemeral = &Ephemeral{}
-			s.Ephemeral.EmptyDirVolumeSource = v1.EmptyDirVolumeSource{}
-			changed = true
-		}
-	} else {
-		if s.Persistence == nil {
-			s.StorageType = "persistence"
-			s.Persistence = &Persistence{}
-			changed = true
-		}
-		if s.Persistence.withDefaults() {
-			s.StorageType = "persistence"
-			changed = true
-		}
-	}
-	if s.MaxUnavailableReplicas < 1 {
-		s.MaxUnavailableReplicas = 1
-		changed = true
-	}
-	return changed
-}
-
-type Probe struct {
-	// +kubebuilder:validation:Minimum=0
-	// +optional
-	InitialDelaySeconds int32 `json:"initialDelaySeconds"`
-	// +kubebuilder:validation:Minimum=0
-	// +optional
-	PeriodSeconds int32 `json:"periodSeconds"`
-	// +kubebuilder:validation:Minimum=0
-	// +optional
-	FailureThreshold int32 `json:"failureThreshold"`
-	// +kubebuilder:validation:Minimum=0
-	// +optional
-	SuccessThreshold int32 `json:"successThreshold"`
-	// +kubebuilder:validation:Minimum=0
-	// +optional
-	TimeoutSeconds int32 `json:"timeoutSeconds"`
-}
-
-// Generate CRD using kubebuilder
-// +kubebuilder:object:root=true
-// +kubebuilder:subresource:status
-// +kubebuilder:resource:shortName=zk
-// +kubebuilder:printcolumn:name="Replicas",type=integer,JSONPath=`.spec.replicas`,description="The number of ZooKeeper servers in the ensemble"
-// +kubebuilder:printcolumn:name="Ready Replicas",type=integer,JSONPath=`.status.readyReplicas`,description="The number of ZooKeeper servers in the ensemble that are in a Ready state"
-// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.status.currentVersion`,description="The current Zookeeper version"
-// +kubebuilder:printcolumn:name="Desired Version",type=string,JSONPath=`.spec.image.tag`,description="The desired Zookeeper version"
-// +kubebuilder:printcolumn:name="Internal Endpoint",type=string,JSONPath=`.status.internalClientEndpoint`,description="Client endpoint internal to cluster network"
-// +kubebuilder:printcolumn:name="External Endpoint",type=string,JSONPath=`.status.externalClientEndpoint`,description="Client endpoint external to cluster network via LoadBalancer"
-// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
-// +k8s:openapi-gen=true
-
-// ZookeeperCluster is the Schema for the zookeeperclusters API
-type ZookeeperCluster struct {
-	metav1.TypeMeta   `json:",inline"`
-	metav1.ObjectMeta `json:"metadata,omitempty"`
-
-	Spec   ZookeeperClusterSpec   `json:"spec,omitempty"`
-	Status ZookeeperClusterStatus `json:"status,omitempty"`
-}
-
-// WithDefaults set default values when not defined in the spec.
-func (z *ZookeeperCluster) WithDefaults() bool {
-	return z.Spec.withDefaults(z)
-}
-
-// ConfigMapName returns the name of the cluster config-map
-func (z *ZookeeperCluster) ConfigMapName() string {
-	return fmt.Sprintf("%s-configmap", z.GetName())
-}
-
-// GetKubernetesClusterDomain returns the cluster domain of kubernetes
-func (z *ZookeeperCluster) GetKubernetesClusterDomain() string {
-	if z.Spec.KubernetesClusterDomain == "" {
-		return "cluster.local"
-	}
-	return z.Spec.KubernetesClusterDomain
-}
-
-// ZookeeperPorts returns a struct of ports
-func (z *ZookeeperCluster) ZookeeperPorts() Ports {
-	ports := Ports{}
-	for _, p := range z.Spec.Ports {
-		if p.Name == "client" {
-			ports.Client = p.ContainerPort
-		} else if p.Name == "quorum" {
-			ports.Quorum = p.ContainerPort
-		} else if p.Name == "leader-election" {
-			ports.Leader = p.ContainerPort
-		} else if p.Name == "metrics" {
-			ports.Metrics = p.ContainerPort
-		} else if p.Name == "admin-server" {
-			ports.AdminServer = p.ContainerPort
-		}
-	}
-	return ports
-}
-
-// GetClientServiceName returns the name of the client service for the cluster
-func (z *ZookeeperCluster) GetClientServiceName() string {
-	return fmt.Sprintf("%s-client", z.GetName())
-}
-
-// GetAdminServerServiceName returns the name of the admin server service for the cluster
-func (z *ZookeeperCluster) GetAdminServerServiceName() string {
-	return fmt.Sprintf("%s-admin-server", z.GetName())
-}
-
-func (z *ZookeeperCluster) GetTriggerRollingRestart() bool {
-	return z.Spec.TriggerRollingRestart
-}
-
-// set the value of triggerRollingRestart function
-func (z *ZookeeperCluster) SetTriggerRollingRestart(val bool) {
-	z.Spec.TriggerRollingRestart = val
-}
-
-// Ports groups the ports for a zookeeper cluster node for easy access
-type Ports struct {
-	Client      int32
-	Quorum      int32
-	Leader      int32
-	Metrics     int32
-	AdminServer int32
-}
-
-// ContainerImage defines the fields needed for a Docker repository image. The
-// format here matches the predominant format used in Helm charts.
-type ContainerImage struct {
-	Repository string `json:"repository,omitempty"`
-	Tag        string `json:"tag,omitempty"`
-	// +kubebuilder:validation:Enum="Always";"Never";"IfNotPresent"
-	PullPolicy v1.PullPolicy `json:"pullPolicy,omitempty"`
-}
-
-func (c *ContainerImage) withDefaults() (changed bool) {
-	if c.Repository == "" {
-		changed = true
-		c.Repository = DefaultZkContainerRepository
-	}
-	if c.Tag == "" {
-		changed = true
-		c.Tag = DefaultZkContainerVersion
-	}
-	if c.PullPolicy == "" {
-		changed = true
-		c.PullPolicy = DefaultZkContainerPolicy
-	}
-	return changed
-}
-
-// ToString formats a container image struct as a docker compatible repository
-// string.
-func (c *ContainerImage) ToString() string {
-	return fmt.Sprintf("%s:%s", c.Repository, c.Tag)
-}
-
-// PodPolicy defines the common pod configuration for Pods, including when used
-// in deployments, stateful-sets, etc.
-type PodPolicy struct {
-	// Labels specifies the labels to attach to pods the operator creates for
-	// the zookeeper cluster.
-	Labels map[string]string `json:"labels,omitempty"`
-
-	// NodeSelector specifies a map of key-value pairs. For the pod to be
-	// eligible to run on a node, the node must have each of the indicated
-	// key-value pairs as labels.
-	NodeSelector map[string]string `json:"nodeSelector,omitempty"`
-
-	// The scheduling constraints on pods.
-	Affinity *v1.Affinity `json:"affinity,omitempty"`
-
-	// Resources is the resource requirements for the container.
-	// This field cannot be updated once the cluster is created.
-	Resources v1.ResourceRequirements `json:"resources,omitempty"`
-
-	// Tolerations specifies the pod's tolerations.
-	Tolerations []v1.Toleration `json:"tolerations,omitempty"`
-
-	// List of environment variables to set in the container.
-	// This field cannot be updated.
-	Env []v1.EnvVar `json:"env,omitempty"`
-
-	// Annotations specifies the annotations to attach to pods the operator
-	// creates.
-	Annotations map[string]string `json:"annotations,omitempty"`
-
-	// SecurityContext specifies the security context for the entire pod
-	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context
-	SecurityContext *v1.PodSecurityContext `json:"securityContext,omitempty"`
-
-	// +kubebuilder:validation:Minimum=0
-	// TerminationGracePeriodSeconds is the amount of time that kubernetes will
-	// give for a pod instance to shutdown normally.
-	// The default value is 30.
-	TerminationGracePeriodSeconds int64 `json:"terminationGracePeriodSeconds,omitempty"`
-	// Service Account to be used in pods
-	ServiceAccountName string `json:"serviceAccountName,omitempty"`
-	// ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images
-	ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
-}
-
-func (p *PodPolicy) withDefaults(z *ZookeeperCluster) (changed bool) {
-	if p.Labels == nil {
-		p.Labels = map[string]string{}
-		changed = true
-	}
-	if p.TerminationGracePeriodSeconds == 0 {
-		p.TerminationGracePeriodSeconds = DefaultTerminationGracePeriod
-		changed = true
-	}
-	if p.ServiceAccountName == "" {
-		p.ServiceAccountName = "default"
-		changed = true
-	}
-	if z.Spec.Pod.Labels == nil {
-		p.Labels = map[string]string{}
-		changed = true
-	}
-	if _, ok := p.Labels["app"]; !ok {
-		p.Labels["app"] = z.GetName()
-		changed = true
-	}
-	if _, ok := p.Labels["release"]; !ok {
-		p.Labels["release"] = z.GetName()
-		changed = true
-	}
-	if p.Affinity == nil {
-		p.Affinity = &v1.Affinity{
-			PodAntiAffinity: &v1.PodAntiAffinity{
-				PreferredDuringSchedulingIgnoredDuringExecution: []v1.WeightedPodAffinityTerm{
-					{
-						Weight: 20,
-						PodAffinityTerm: v1.PodAffinityTerm{
-							TopologyKey: "kubernetes.io/hostname",
-							LabelSelector: &metav1.LabelSelector{
-								MatchExpressions: []metav1.LabelSelectorRequirement{
-									{
-										Key:      "app",
-										Operator: metav1.LabelSelectorOpIn,
-										Values:   []string{z.GetName()},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		}
-		changed = true
-	}
-	return changed
-}
-
-type AdminServerServicePolicy struct {
-	// Annotations specifies the annotations to attach to AdminServer service the operator
-	// creates.
-	Annotations map[string]string `json:"annotations,omitempty"`
-
-	External bool `json:"external,omitempty"`
-}
-
-type ClientServicePolicy struct {
-	// Annotations specifies the annotations to attach to client service the operator
-	// creates.
-	Annotations map[string]string `json:"annotations,omitempty"`
-}
-
-type HeadlessServicePolicy struct {
-	// Annotations specifies the annotations to attach to headless service the operator
-	// creates.
-	Annotations map[string]string `json:"annotations,omitempty"`
-}
-
-func (s *Probes) withDefaults() (changed bool) {
-	if s.ReadinessProbe == nil {
-		changed = true
-		s.ReadinessProbe = &Probe{}
-		s.ReadinessProbe.InitialDelaySeconds = DefaultReadinessProbeInitialDelaySeconds
-		s.ReadinessProbe.PeriodSeconds = DefaultReadinessProbePeriodSeconds
-		s.ReadinessProbe.FailureThreshold = DefaultReadinessProbeFailureThreshold
-		s.ReadinessProbe.SuccessThreshold = DefaultReadinessProbeSuccessThreshold
-		s.ReadinessProbe.TimeoutSeconds = DefaultReadinessProbeTimeoutSeconds
-	}
-
-	if s.LivenessProbe == nil {
-		changed = true
-		s.LivenessProbe = &Probe{}
-		s.LivenessProbe.InitialDelaySeconds = DefaultLivenessProbeInitialDelaySeconds
-		s.LivenessProbe.PeriodSeconds = DefaultLivenessProbePeriodSeconds
-		s.LivenessProbe.FailureThreshold = DefaultLivenessProbeFailureThreshold
-		s.LivenessProbe.TimeoutSeconds = DefaultLivenessProbeTimeoutSeconds
-	}
-
-	return changed
-}
-
-// ZookeeperConfig is the current configuration of each Zookeeper node, which
-// sets these values in the config-map
-type ZookeeperConfig struct {
-	// InitLimit is the amount of time, in ticks, to allow followers to connect
-	// and sync to a leader.
-	//
-	// Default value is 10.
-	InitLimit int `json:"initLimit,omitempty"`
-
-	// TickTime is the length of a single tick, which is the basic time unit used
-	// by Zookeeper, as measured in milliseconds
-	//
-	// The default value is 2000.
-	TickTime int `json:"tickTime,omitempty"`
-
-	// SyncLimit is the amount of time, in ticks, to allow followers to sync with
-	// Zookeeper.
-	//
-	// The default value is 2.
-	SyncLimit int `json:"syncLimit,omitempty"`
-
-	// Clients can submit requests faster than ZooKeeper can process them, especially
-	// if there are a lot of clients. Zookeeper will throttle Clients so that requests
-	// won't exceed global outstanding limit.
-	//
-	// The default value is 1000
-	GlobalOutstandingLimit int `json:"globalOutstandingLimit,omitempty"`
-
-	// To avoid seeks ZooKeeper allocates space in the transaction log file in
-	// blocks of preAllocSize kilobytes
-	//
-	// The default value is 64M
-	PreAllocSize int `json:"preAllocSize,omitempty"`
-
-	// ZooKeeper records its transactions using snapshots and a transaction log
-	// The number of transactions recorded in the transaction log before a snapshot
-	// can be taken is determined by snapCount
-	//
-	// The default value is 100,000
-	SnapCount int `json:"snapCount,omitempty"`
-
-	// Zookeeper maintains an in-memory list of last committed requests for fast
-	// synchronization with followers
-	//
-	// The default value is 500
-	CommitLogCount int `json:"commitLogCount,omitempty"`
-
-	// Snapshot size limit in Kb
-	//
-	// The defult value is 4GB
-	SnapSizeLimitInKb int `json:"snapSizeLimitInKb,omitempty"`
-
-	// Limits the total number of concurrent connections that can be made to a
-	//zookeeper server
-	//
-	// The defult value is 0, indicating no limit
-	MaxCnxns int `json:"maxCnxns,omitempty"`
-
-	// Limits the number of concurrent connections that a single client, identified
-	// by IP address, may make to a single member of the ZooKeeper ensemble.
-	//
-	// The default value is 60
-	MaxClientCnxns int `json:"maxClientCnxns,omitempty"`
-
-	// The minimum session timeout in milliseconds that the server will allow the
-	// client to negotiate
-	//
-	// The default value is 4000
-	MinSessionTimeout int `json:"minSessionTimeout,omitempty"`
-
-	// The maximum session timeout in milliseconds that the server will allow the
-	// client to negotiate.
-	//
-	// The default value is 40000
-	MaxSessionTimeout int `json:"maxSessionTimeout,omitempty"`
-
-	// Retain the snapshots according to retain count
-	//
-	// The default value is 3
-	AutoPurgeSnapRetainCount int `json:"autoPurgeSnapRetainCount,omitempty"`
-
-	// The time interval in hours for which the purge task has to be triggered
-	//
-	// Disabled by default
-	AutoPurgePurgeInterval int `json:"autoPurgePurgeInterval,omitempty"`
-
-	// QuorumListenOnAllIPs when set to true the ZooKeeper server will listen for
-	// connections from its peers on all available IP addresses, and not only the
-	// address configured in the server list of the configuration file. It affects
-	// the connections handling the ZAB protocol and the Fast Leader Election protocol.
-	//
-	// The default value is false.
-	QuorumListenOnAllIPs bool `json:"quorumListenOnAllIPs,omitempty"`
-
-	// key-value map of additional zookeeper configuration parameters
-	// +kubebuilder:pruning:PreserveUnknownFields
-	// +optional
-	AdditionalConfig map[string]string `json:"additionalConfig,omitempty"`
-}
-
-func (c *ZookeeperConfig) withDefaults() (changed bool) {
-	if c.InitLimit == 0 {
-		changed = true
-		c.InitLimit = 10
-	}
-	if c.TickTime == 0 {
-		changed = true
-		c.TickTime = 2000
-	}
-	if c.SyncLimit == 0 {
-		changed = true
-		c.SyncLimit = 2
-	}
-	if c.GlobalOutstandingLimit == 0 {
-		changed = true
-		c.GlobalOutstandingLimit = 1000
-	}
-	if c.PreAllocSize == 0 {
-		changed = true
-		c.PreAllocSize = 65536
-	}
-	if c.SnapCount == 0 {
-		changed = true
-		c.SnapCount = 10000
-	}
-	if c.CommitLogCount == 0 {
-		changed = true
-		c.CommitLogCount = 500
-	}
-	if c.SnapSizeLimitInKb == 0 {
-		changed = true
-		c.SnapSizeLimitInKb = 4194304
-	}
-	if c.MaxClientCnxns == 0 {
-		changed = true
-		c.MaxClientCnxns = 60
-	}
-	if c.MinSessionTimeout == 0 {
-		changed = true
-		c.MinSessionTimeout = 2 * c.TickTime
-	}
-	if c.MaxSessionTimeout == 0 {
-		changed = true
-		c.MaxSessionTimeout = 20 * c.TickTime
-	}
-	if c.AutoPurgeSnapRetainCount == 0 {
-		changed = true
-		c.AutoPurgeSnapRetainCount = 3
-	}
-	if c.AutoPurgePurgeInterval == 0 {
-		changed = true
-		c.AutoPurgePurgeInterval = 1
-	}
-
-	return changed
-}
-
-type Persistence struct {
-	// VolumeReclaimPolicy is a zookeeper operator configuration. If it's set to Delete,
-	// the corresponding PVCs will be deleted by the operator when zookeeper cluster is deleted.
-	// The default value is Retain.
-	// +kubebuilder:validation:Enum="Delete";"Retain"
-	VolumeReclaimPolicy VolumeReclaimPolicy `json:"reclaimPolicy,omitempty"`
-	// PersistentVolumeClaimSpec is the spec to describe PVC for the container
-	// This field is optional. If no PVC is specified default persistentvolume
-	// will get created.
-	PersistentVolumeClaimSpec v1.PersistentVolumeClaimSpec `json:"spec,omitempty"`
-	// Annotations specifies the annotations to attach to pvc the operator
-	// creates.
-	Annotations map[string]string `json:"annotations,omitempty"`
-}
-
-type Ephemeral struct {
-	//EmptyDirVolumeSource is optional and this will create the emptydir volume
-	//It has two parameters Medium and SizeLimit which are optional as well
-	//Medium specifies What type of storage medium should back this directory.
-	//SizeLimit specifies Total amount of local storage required for this EmptyDir volume.
-	EmptyDirVolumeSource v1.EmptyDirVolumeSource `json:"emptydirvolumesource,omitempty"`
-}
-
-func (p *Persistence) withDefaults() (changed bool) {
-	if !p.VolumeReclaimPolicy.isValid() {
-		changed = true
-		p.VolumeReclaimPolicy = VolumeReclaimPolicyRetain
-	}
-	p.PersistentVolumeClaimSpec.AccessModes = []v1.PersistentVolumeAccessMode{
-		v1.ReadWriteOnce,
-	}
-
-	storage, _ := p.PersistentVolumeClaimSpec.Resources.Requests["storage"]
-	if storage.IsZero() {
-		p.PersistentVolumeClaimSpec.Resources.Requests = v1.ResourceList{
-			v1.ResourceStorage: resource.MustParse(DefaultZookeeperCacheVolumeSize),
-		}
-		changed = true
-	}
-	return changed
-}
-
-func (v VolumeReclaimPolicy) isValid() bool {
-	if v != VolumeReclaimPolicyDelete && v != VolumeReclaimPolicyRetain {
-		return false
-	}
-	return true
-}
-
-type VolumeReclaimPolicy string
-
-const (
-	VolumeReclaimPolicyRetain VolumeReclaimPolicy = "Retain"
-	VolumeReclaimPolicyDelete VolumeReclaimPolicy = "Delete"
-)
-
-// +kubebuilder:object:root=true
-
-// ZookeeperClusterList contains a list of ZookeeperCluster
-type ZookeeperClusterList struct {
-	metav1.TypeMeta `json:",inline"`
-	metav1.ListMeta `json:"metadata,omitempty"`
-	Items           []ZookeeperCluster `json:"items"`
-}
-
-func init() {
-	SchemeBuilder.Register(&ZookeeperCluster{}, &ZookeeperClusterList{})
-}
diff --git a/controllers/zk_api/zkstatus.go b/controllers/zk_api/zkstatus.go
deleted file mode 100644
index 94558fe..0000000
--- a/controllers/zk_api/zkstatus.go
+++ /dev/null
@@ -1,223 +0,0 @@
-/**
- * Copyright (c) 2018 Dell Inc., or its subsidiaries. All Rights Reserved.
- *
- * 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
- */
-
-package zk_api
-
-import (
-	"time"
-
-	v1 "k8s.io/api/core/v1"
-)
-
-type ClusterConditionType string
-
-const (
-	ClusterConditionPodsReady ClusterConditionType = "PodsReady"
-	ClusterConditionUpgrading                      = "Upgrading"
-	ClusterConditionError                          = "Error"
-
-	// Reasons for cluster upgrading condition
-	UpdatingZookeeperReason = "Updating Zookeeper"
-	UpgradeErrorReason      = "Upgrade Error"
-)
-
-// ZookeeperClusterStatus defines the observed state of ZookeeperCluster
-type ZookeeperClusterStatus struct {
-	// Members is the zookeeper members in the cluster
-	Members MembersStatus `json:"members,omitempty"`
-
-	// Replicas is the number of number of desired replicas in the cluster
-	Replicas int32 `json:"replicas,omitempty"`
-
-	// ReadyReplicas is the number of number of ready replicas in the cluster
-	ReadyReplicas int32 `json:"readyReplicas,omitempty"`
-
-	// InternalClientEndpoint is the internal client IP and port
-	InternalClientEndpoint string `json:"internalClientEndpoint,omitempty"`
-
-	// ExternalClientEndpoint is the internal client IP and port
-	ExternalClientEndpoint string `json:"externalClientEndpoint,omitempty"`
-
-	MetaRootCreated bool `json:"metaRootCreated,omitempty"`
-
-	// CurrentVersion is the current cluster version
-	CurrentVersion string `json:"currentVersion,omitempty"`
-
-	TargetVersion string `json:"targetVersion,omitempty"`
-
-	// Conditions list all the applied conditions
-	Conditions []ClusterCondition `json:"conditions,omitempty"`
-}
-
-// MembersStatus is the status of the members of the cluster with both
-// ready and unready node membership lists
-type MembersStatus struct {
-	//+nullable
-	Ready []string `json:"ready,omitempty"`
-	//+nullable
-	Unready []string `json:"unready,omitempty"`
-}
-
-// ClusterCondition shows the current condition of a Zookeeper cluster.
-// Comply with k8s API conventions
-type ClusterCondition struct {
-	// Type of Zookeeper cluster condition.
-	Type ClusterConditionType `json:"type,omitempty"`
-
-	// Status of the condition, one of True, False, Unknown.
-	Status v1.ConditionStatus `json:"status,omitempty"`
-
-	// The reason for the condition's last transition.
-	Reason string `json:"reason,omitempty"`
-
-	// A human readable message indicating details about the transition.
-	Message string `json:"message,omitempty"`
-
-	// The last time this condition was updated.
-	LastUpdateTime string `json:"lastUpdateTime,omitempty"`
-
-	// Last time the condition transitioned from one status to another.
-	LastTransitionTime string `json:"lastTransitionTime,omitempty"`
-}
-
-func (zs *ZookeeperClusterStatus) Init() {
-	// Initialise conditions
-	conditionTypes := []ClusterConditionType{
-		ClusterConditionPodsReady,
-		ClusterConditionUpgrading,
-		ClusterConditionError,
-	}
-	for _, conditionType := range conditionTypes {
-		if _, condition := zs.GetClusterCondition(conditionType); condition == nil {
-			c := newClusterCondition(conditionType, v1.ConditionFalse, "", "")
-			zs.setClusterCondition(*c)
-		}
-	}
-}
-
-func newClusterCondition(condType ClusterConditionType, status v1.ConditionStatus, reason, message string) *ClusterCondition {
-	return &ClusterCondition{
-		Type:               condType,
-		Status:             status,
-		Reason:             reason,
-		Message:            message,
-		LastUpdateTime:     "",
-		LastTransitionTime: "",
-	}
-}
-
-func (zs *ZookeeperClusterStatus) SetPodsReadyConditionTrue() {
-	c := newClusterCondition(ClusterConditionPodsReady, v1.ConditionTrue, "", "")
-	zs.setClusterCondition(*c)
-}
-
-func (zs *ZookeeperClusterStatus) SetPodsReadyConditionFalse() {
-	c := newClusterCondition(ClusterConditionPodsReady, v1.ConditionFalse, "", "")
-	zs.setClusterCondition(*c)
-}
-
-func (zs *ZookeeperClusterStatus) SetUpgradingConditionTrue(reason, message string) {
-	c := newClusterCondition(ClusterConditionUpgrading, v1.ConditionTrue, reason, message)
-	zs.setClusterCondition(*c)
-}
-
-func (zs *ZookeeperClusterStatus) SetUpgradingConditionFalse() {
-	c := newClusterCondition(ClusterConditionUpgrading, v1.ConditionFalse, "", "")
-	zs.setClusterCondition(*c)
-}
-
-func (zs *ZookeeperClusterStatus) SetErrorConditionTrue(reason, message string) {
-	c := newClusterCondition(ClusterConditionError, v1.ConditionTrue, reason, message)
-	zs.setClusterCondition(*c)
-}
-
-func (zs *ZookeeperClusterStatus) SetErrorConditionFalse() {
-	c := newClusterCondition(ClusterConditionError, v1.ConditionFalse, "", "")
-	zs.setClusterCondition(*c)
-}
-
-func (zs *ZookeeperClusterStatus) GetClusterCondition(t ClusterConditionType) (int, *ClusterCondition) {
-	for i, c := range zs.Conditions {
-		if t == c.Type {
-			return i, &c
-		}
-	}
-	return -1, nil
-}
-
-func (zs *ZookeeperClusterStatus) setClusterCondition(newCondition ClusterCondition) {
-	now := time.Now().Format(time.RFC3339)
-	position, existingCondition := zs.GetClusterCondition(newCondition.Type)
-
-	if existingCondition == nil {
-		zs.Conditions = append(zs.Conditions, newCondition)
-		return
-	}
-
-	if existingCondition.Status != newCondition.Status {
-		existingCondition.Status = newCondition.Status
-		existingCondition.LastTransitionTime = now
-		existingCondition.LastUpdateTime = now
-	}
-
-	if existingCondition.Reason != newCondition.Reason || existingCondition.Message != newCondition.Message {
-		existingCondition.Reason = newCondition.Reason
-		existingCondition.Message = newCondition.Message
-		existingCondition.LastUpdateTime = now
-	}
-
-	zs.Conditions[position] = *existingCondition
-}
-
-func (zs *ZookeeperClusterStatus) IsClusterInUpgradeFailedState() bool {
-	_, errorCondition := zs.GetClusterCondition(ClusterConditionError)
-	if errorCondition == nil {
-		return false
-	}
-	if errorCondition.Status == v1.ConditionTrue && errorCondition.Reason == "UpgradeFailed" {
-		return true
-	}
-	return false
-}
-
-func (zs *ZookeeperClusterStatus) IsClusterInUpgradingState() bool {
-	_, upgradeCondition := zs.GetClusterCondition(ClusterConditionUpgrading)
-	if upgradeCondition == nil {
-		return false
-	}
-	if upgradeCondition.Status == v1.ConditionTrue {
-		return true
-	}
-	return false
-}
-
-func (zs *ZookeeperClusterStatus) IsClusterInReadyState() bool {
-	_, readyCondition := zs.GetClusterCondition(ClusterConditionPodsReady)
-	if readyCondition != nil && readyCondition.Status == v1.ConditionTrue {
-		return true
-	}
-	return false
-}
-
-func (zs *ZookeeperClusterStatus) UpdateProgress(reason, updatedReplicas string) {
-	if zs.IsClusterInUpgradingState() {
-		// Set the upgrade condition reason to be UpgradingZookeeperReason, message to be the upgradedReplicas
-		zs.SetUpgradingConditionTrue(reason, updatedReplicas)
-	}
-}
-
-func (zs *ZookeeperClusterStatus) GetLastCondition() (lastCondition *ClusterCondition) {
-	if zs.IsClusterInUpgradingState() {
-		_, lastCondition := zs.GetClusterCondition(ClusterConditionUpgrading)
-		return lastCondition
-	}
-	// nothing to do if we are not upgrading
-	return nil
-}
diff --git a/controllers/zk_api/zz_generated.deepcopy.go b/controllers/zk_api/zz_generated.deepcopy.go
deleted file mode 100644
index 1fe4317..0000000
--- a/controllers/zk_api/zz_generated.deepcopy.go
+++ /dev/null
@@ -1,487 +0,0 @@
-//go:build !ignore_autogenerated
-// +build !ignore_autogenerated
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-// Code generated by controller-gen. DO NOT EDIT.
-
-package zk_api
-
-import (
-	"k8s.io/api/core/v1"
-	runtime "k8s.io/apimachinery/pkg/runtime"
-)
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AdminServerServicePolicy) DeepCopyInto(out *AdminServerServicePolicy) {
-	*out = *in
-	if in.Annotations != nil {
-		in, out := &in.Annotations, &out.Annotations
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdminServerServicePolicy.
-func (in *AdminServerServicePolicy) DeepCopy() *AdminServerServicePolicy {
-	if in == nil {
-		return nil
-	}
-	out := new(AdminServerServicePolicy)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ClientServicePolicy) DeepCopyInto(out *ClientServicePolicy) {
-	*out = *in
-	if in.Annotations != nil {
-		in, out := &in.Annotations, &out.Annotations
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientServicePolicy.
-func (in *ClientServicePolicy) DeepCopy() *ClientServicePolicy {
-	if in == nil {
-		return nil
-	}
-	out := new(ClientServicePolicy)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ClusterCondition) DeepCopyInto(out *ClusterCondition) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCondition.
-func (in *ClusterCondition) DeepCopy() *ClusterCondition {
-	if in == nil {
-		return nil
-	}
-	out := new(ClusterCondition)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ContainerImage) DeepCopyInto(out *ContainerImage) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerImage.
-func (in *ContainerImage) DeepCopy() *ContainerImage {
-	if in == nil {
-		return nil
-	}
-	out := new(ContainerImage)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Ephemeral) DeepCopyInto(out *Ephemeral) {
-	*out = *in
-	in.EmptyDirVolumeSource.DeepCopyInto(&out.EmptyDirVolumeSource)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ephemeral.
-func (in *Ephemeral) DeepCopy() *Ephemeral {
-	if in == nil {
-		return nil
-	}
-	out := new(Ephemeral)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *HeadlessServicePolicy) DeepCopyInto(out *HeadlessServicePolicy) {
-	*out = *in
-	if in.Annotations != nil {
-		in, out := &in.Annotations, &out.Annotations
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeadlessServicePolicy.
-func (in *HeadlessServicePolicy) DeepCopy() *HeadlessServicePolicy {
-	if in == nil {
-		return nil
-	}
-	out := new(HeadlessServicePolicy)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MembersStatus) DeepCopyInto(out *MembersStatus) {
-	*out = *in
-	if in.Ready != nil {
-		in, out := &in.Ready, &out.Ready
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.Unready != nil {
-		in, out := &in.Unready, &out.Unready
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MembersStatus.
-func (in *MembersStatus) DeepCopy() *MembersStatus {
-	if in == nil {
-		return nil
-	}
-	out := new(MembersStatus)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Persistence) DeepCopyInto(out *Persistence) {
-	*out = *in
-	in.PersistentVolumeClaimSpec.DeepCopyInto(&out.PersistentVolumeClaimSpec)
-	if in.Annotations != nil {
-		in, out := &in.Annotations, &out.Annotations
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Persistence.
-func (in *Persistence) DeepCopy() *Persistence {
-	if in == nil {
-		return nil
-	}
-	out := new(Persistence)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *PodPolicy) DeepCopyInto(out *PodPolicy) {
-	*out = *in
-	if in.Labels != nil {
-		in, out := &in.Labels, &out.Labels
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.NodeSelector != nil {
-		in, out := &in.NodeSelector, &out.NodeSelector
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Affinity != nil {
-		in, out := &in.Affinity, &out.Affinity
-		*out = new(v1.Affinity)
-		(*in).DeepCopyInto(*out)
-	}
-	in.Resources.DeepCopyInto(&out.Resources)
-	if in.Tolerations != nil {
-		in, out := &in.Tolerations, &out.Tolerations
-		*out = make([]v1.Toleration, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.Env != nil {
-		in, out := &in.Env, &out.Env
-		*out = make([]v1.EnvVar, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.Annotations != nil {
-		in, out := &in.Annotations, &out.Annotations
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.SecurityContext != nil {
-		in, out := &in.SecurityContext, &out.SecurityContext
-		*out = new(v1.PodSecurityContext)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.ImagePullSecrets != nil {
-		in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
-		*out = make([]v1.LocalObjectReference, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodPolicy.
-func (in *PodPolicy) DeepCopy() *PodPolicy {
-	if in == nil {
-		return nil
-	}
-	out := new(PodPolicy)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Ports) DeepCopyInto(out *Ports) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ports.
-func (in *Ports) DeepCopy() *Ports {
-	if in == nil {
-		return nil
-	}
-	out := new(Ports)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Probe) DeepCopyInto(out *Probe) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probe.
-func (in *Probe) DeepCopy() *Probe {
-	if in == nil {
-		return nil
-	}
-	out := new(Probe)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Probes) DeepCopyInto(out *Probes) {
-	*out = *in
-	if in.ReadinessProbe != nil {
-		in, out := &in.ReadinessProbe, &out.ReadinessProbe
-		*out = new(Probe)
-		**out = **in
-	}
-	if in.LivenessProbe != nil {
-		in, out := &in.LivenessProbe, &out.LivenessProbe
-		*out = new(Probe)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probes.
-func (in *Probes) DeepCopy() *Probes {
-	if in == nil {
-		return nil
-	}
-	out := new(Probes)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ZookeeperCluster) DeepCopyInto(out *ZookeeperCluster) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
-	in.Spec.DeepCopyInto(&out.Spec)
-	in.Status.DeepCopyInto(&out.Status)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZookeeperCluster.
-func (in *ZookeeperCluster) DeepCopy() *ZookeeperCluster {
-	if in == nil {
-		return nil
-	}
-	out := new(ZookeeperCluster)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ZookeeperCluster) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ZookeeperClusterList) DeepCopyInto(out *ZookeeperClusterList) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ListMeta.DeepCopyInto(&out.ListMeta)
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]ZookeeperCluster, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZookeeperClusterList.
-func (in *ZookeeperClusterList) DeepCopy() *ZookeeperClusterList {
-	if in == nil {
-		return nil
-	}
-	out := new(ZookeeperClusterList)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *ZookeeperClusterList) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ZookeeperClusterSpec) DeepCopyInto(out *ZookeeperClusterSpec) {
-	*out = *in
-	out.Image = in.Image
-	if in.Labels != nil {
-		in, out := &in.Labels, &out.Labels
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-	if in.Ports != nil {
-		in, out := &in.Ports, &out.Ports
-		*out = make([]v1.ContainerPort, len(*in))
-		copy(*out, *in)
-	}
-	in.Pod.DeepCopyInto(&out.Pod)
-	in.AdminServerService.DeepCopyInto(&out.AdminServerService)
-	in.ClientService.DeepCopyInto(&out.ClientService)
-	in.HeadlessService.DeepCopyInto(&out.HeadlessService)
-	if in.Persistence != nil {
-		in, out := &in.Persistence, &out.Persistence
-		*out = new(Persistence)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.Ephemeral != nil {
-		in, out := &in.Ephemeral, &out.Ephemeral
-		*out = new(Ephemeral)
-		(*in).DeepCopyInto(*out)
-	}
-	in.Conf.DeepCopyInto(&out.Conf)
-	if in.Containers != nil {
-		in, out := &in.Containers, &out.Containers
-		*out = make([]v1.Container, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.InitContainers != nil {
-		in, out := &in.InitContainers, &out.InitContainers
-		*out = make([]v1.Container, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.Volumes != nil {
-		in, out := &in.Volumes, &out.Volumes
-		*out = make([]v1.Volume, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.VolumeMounts != nil {
-		in, out := &in.VolumeMounts, &out.VolumeMounts
-		*out = make([]v1.VolumeMount, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	if in.Probes != nil {
-		in, out := &in.Probes, &out.Probes
-		*out = new(Probes)
-		(*in).DeepCopyInto(*out)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZookeeperClusterSpec.
-func (in *ZookeeperClusterSpec) DeepCopy() *ZookeeperClusterSpec {
-	if in == nil {
-		return nil
-	}
-	out := new(ZookeeperClusterSpec)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ZookeeperClusterStatus) DeepCopyInto(out *ZookeeperClusterStatus) {
-	*out = *in
-	in.Members.DeepCopyInto(&out.Members)
-	if in.Conditions != nil {
-		in, out := &in.Conditions, &out.Conditions
-		*out = make([]ClusterCondition, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZookeeperClusterStatus.
-func (in *ZookeeperClusterStatus) DeepCopy() *ZookeeperClusterStatus {
-	if in == nil {
-		return nil
-	}
-	out := new(ZookeeperClusterStatus)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ZookeeperConfig) DeepCopyInto(out *ZookeeperConfig) {
-	*out = *in
-	if in.AdditionalConfig != nil {
-		in, out := &in.AdditionalConfig, &out.AdditionalConfig
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZookeeperConfig.
-func (in *ZookeeperConfig) DeepCopy() *ZookeeperConfig {
-	if in == nil {
-		return nil
-	}
-	out := new(ZookeeperConfig)
-	in.DeepCopyInto(out)
-	return out
-}
diff --git a/dependency_licenses.csv b/dependency_licenses.csv
index b57d9e8..d966066 100644
--- a/dependency_licenses.csv
+++ b/dependency_licenses.csv
@@ -8,24 +8,25 @@
 github.com/go-logr/zapr,https://github.com/go-logr/zapr/blob/v1.2.3/LICENSE,Apache-2.0
 github.com/go-openapi/jsonpointer,https://github.com/go-openapi/jsonpointer/blob/v0.19.5/LICENSE,Apache-2.0
 github.com/go-openapi/jsonreference,https://github.com/go-openapi/jsonreference/blob/v0.20.0/LICENSE,Apache-2.0
-github.com/go-openapi/swag,https://github.com/go-openapi/swag/blob/v0.19.14/LICENSE,Apache-2.0
+github.com/go-openapi/swag,https://github.com/go-openapi/swag/blob/v0.21.1/LICENSE,Apache-2.0
 github.com/gogo/protobuf,https://github.com/gogo/protobuf/blob/v1.3.2/LICENSE,BSD-3-Clause
 github.com/golang/groupcache/lru,https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE,Apache-2.0
 github.com/golang/protobuf,https://github.com/golang/protobuf/blob/v1.5.2/LICENSE,BSD-3-Clause
-github.com/google/gnostic,https://github.com/google/gnostic/blob/v0.5.7-v3refs/LICENSE,Apache-2.0
+github.com/google/gnostic,https://github.com/google/gnostic/blob/v0.6.9/LICENSE,Apache-2.0
 github.com/google/go-cmp/cmp,https://github.com/google/go-cmp/blob/v0.5.9/LICENSE,BSD-3-Clause
 github.com/google/gofuzz,https://github.com/google/gofuzz/blob/v1.2.0/LICENSE,Apache-2.0
-github.com/google/uuid,https://github.com/google/uuid/blob/v1.2.0/LICENSE,BSD-3-Clause
-github.com/imdario/mergo,https://github.com/imdario/mergo/blob/v0.3.12/LICENSE,BSD-3-Clause
+github.com/google/uuid,https://github.com/google/uuid/blob/v1.3.0/LICENSE,BSD-3-Clause
+github.com/imdario/mergo,https://github.com/imdario/mergo/blob/v0.3.13/LICENSE,BSD-3-Clause
 github.com/josharian/intern,https://github.com/josharian/intern/blob/v1.0.0/license.md,MIT
 github.com/json-iterator/go,https://github.com/json-iterator/go/blob/v1.1.12/LICENSE,MIT
-github.com/mailru/easyjson,https://github.com/mailru/easyjson/blob/v0.7.6/LICENSE,MIT
+github.com/mailru/easyjson,https://github.com/mailru/easyjson/blob/v0.7.7/LICENSE,MIT
 github.com/matttproud/golang_protobuf_extensions/pbutil,https://github.com/matttproud/golang_protobuf_extensions/blob/v1.0.4/LICENSE,Apache-2.0
 github.com/moby/spdystream,https://github.com/moby/spdystream/blob/v0.2.0/LICENSE,Apache-2.0
 github.com/modern-go/concurrent,https://github.com/modern-go/concurrent/blob/bacd9c7ef1dd/LICENSE,Apache-2.0
 github.com/modern-go/reflect2,https://github.com/modern-go/reflect2/blob/v1.0.2/LICENSE,Apache-2.0
 github.com/munnerz/goautoneg,https://github.com/munnerz/goautoneg/blob/a7dc8b61c822/LICENSE,BSD-3-Clause
 github.com/pkg/errors,https://github.com/pkg/errors/blob/v0.9.1/LICENSE,BSD-2-Clause
+github.com/pravega/zookeeper-operator/api/v1beta1,https://github.com/pravega/zookeeper-operator/blob/v0.2.15/LICENSE,Apache-2.0
 github.com/prometheus/client_golang/prometheus,https://github.com/prometheus/client_golang/blob/v1.14.0/LICENSE,Apache-2.0
 github.com/prometheus/client_model/go,https://github.com/prometheus/client_model/blob/v0.3.0/LICENSE,Apache-2.0
 github.com/prometheus/common,https://github.com/prometheus/common/blob/v0.37.0/LICENSE,Apache-2.0
@@ -33,11 +34,11 @@
 github.com/prometheus/procfs,https://github.com/prometheus/procfs/blob/v0.8.0/LICENSE,Apache-2.0
 github.com/robfig/cron/v3,https://github.com/robfig/cron/blob/v3.0.1/LICENSE,MIT
 github.com/spf13/pflag,https://github.com/spf13/pflag/blob/v1.0.5/LICENSE,BSD-3-Clause
-go.uber.org/atomic,https://github.com/uber-go/atomic/blob/v1.7.0/LICENSE.txt,MIT
-go.uber.org/multierr,https://github.com/uber-go/multierr/blob/v1.6.0/LICENSE.txt,MIT
+go.uber.org/atomic,https://github.com/uber-go/atomic/blob/v1.9.0/LICENSE.txt,MIT
+go.uber.org/multierr,https://github.com/uber-go/multierr/blob/v1.8.0/LICENSE.txt,MIT
 go.uber.org/zap,https://github.com/uber-go/zap/blob/v1.24.0/LICENSE.txt,MIT
 golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.7.0:LICENSE,BSD-3-Clause
-golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/ee480838:LICENSE,BSD-3-Clause
+golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/622c5d57:LICENSE,BSD-3-Clause
 golang.org/x/sys/unix,https://cs.opensource.google/go/x/sys/+/v0.5.0:LICENSE,BSD-3-Clause
 golang.org/x/term,https://cs.opensource.google/go/x/term/+/v0.5.0:LICENSE,BSD-3-Clause
 golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.7.0:LICENSE,BSD-3-Clause
diff --git a/docs/development.md b/docs/development.md
index 59bc4a0..4eab855 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -41,7 +41,7 @@
 
 ```bash
 helm repo add pravega https://charts.pravega.io
-helm install zookeeper-operator pravega/zookeeper-operator --version 0.2.14
+helm install zookeeper-operator pravega/zookeeper-operator --version 0.2.15
 ```
 
 Install necessary dependencies for building and deploying the operator.
diff --git a/docs/upgrade-notes.md b/docs/upgrade-notes.md
index dc9a0be..34c69a3 100644
--- a/docs/upgrade-notes.md
+++ b/docs/upgrade-notes.md
@@ -114,6 +114,12 @@
   If you are unable to use a newer version of Kubernetes, please install the `v0.6.0` version of the Solr Operator for use with Kubernetes `1.20` and below.
   See the [version compatibility matrix](#kubernetes-versions) for more information.
 
+- The required version of the [Zookeeper Operator](https://github.com/pravega/zookeeper-operator) to use with this version has been upgraded from `v0.2.14` to `v0.2.15`.
+  If you use the Solr Operator helm chart, then by default the new version of the Zookeeper Operator will be installed as well.
+  Refer to the helm chart documentation if you want to manage the Zookeeper Operator installation yourself.  
+  Please refer to the [Zookeeper Operator release notes](https://github.com/pravega/zookeeper-operator/releases) before upgrading.
+  Make sure to install the correct version of the Zookeeper Operator CRDs, as [shown above](#upgrading-the-zookeeper-operator).
+
 - `PodDisruptionBudgets` are now created alongside SolrCloud instances.
   The maximum number of pods allowed down at any given time is aligned with the [Managed Update settings](solr-cloud/solr-cloud-crd.md#update-strategy) provided in the spec.
   If this is not provided, the default setting (`25%`) is used.
diff --git a/go.mod b/go.mod
index 9ce85c8..80bdf95 100644
--- a/go.mod
+++ b/go.mod
@@ -7,6 +7,7 @@
 	github.com/go-logr/logr v1.2.3
 	github.com/onsi/ginkgo/v2 v2.6.0
 	github.com/onsi/gomega v1.24.1
+	github.com/pravega/zookeeper-operator v0.2.15
 	github.com/robfig/cron/v3 v3.0.1
 	github.com/stretchr/testify v1.8.1
 	golang.org/x/net v0.7.0
@@ -50,22 +51,22 @@
 	github.com/go-logr/zapr v1.2.3 // indirect
 	github.com/go-openapi/jsonpointer v0.19.5 // indirect
 	github.com/go-openapi/jsonreference v0.20.0 // indirect
-	github.com/go-openapi/swag v0.19.14 // indirect
+	github.com/go-openapi/swag v0.21.1 // indirect
 	github.com/gobwas/glob v0.2.3 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/btree v1.0.1 // indirect
-	github.com/google/gnostic v0.5.7-v3refs // indirect
+	github.com/google/gnostic v0.6.9 // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
-	github.com/google/uuid v1.2.0 // indirect
+	github.com/google/uuid v1.3.0 // indirect
 	github.com/gorilla/mux v1.8.0 // indirect
 	github.com/gosuri/uitable v0.0.4 // indirect
 	github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
 	github.com/huandu/xstrings v1.3.3 // indirect
-	github.com/imdario/mergo v0.3.12 // indirect
+	github.com/imdario/mergo v0.3.13 // indirect
 	github.com/inconshreveable/mousetrap v1.0.1 // indirect
 	github.com/jmoiron/sqlx v1.3.5 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
@@ -75,7 +76,7 @@
 	github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
 	github.com/lib/pq v1.10.7 // indirect
 	github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
-	github.com/mailru/easyjson v0.7.6 // indirect
+	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.12 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/mattn/go-runewidth v0.0.9 // indirect
@@ -112,11 +113,11 @@
 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect
 	github.com/xlab/treeprint v1.1.0 // indirect
 	go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
-	go.uber.org/atomic v1.7.0 // indirect
-	go.uber.org/multierr v1.6.0 // indirect
+	go.uber.org/atomic v1.9.0 // indirect
+	go.uber.org/multierr v1.8.0 // indirect
 	go.uber.org/zap v1.24.0 // indirect
 	golang.org/x/crypto v0.5.0 // indirect
-	golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
+	golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 // indirect
 	golang.org/x/sync v0.1.0 // indirect
 	golang.org/x/sys v0.5.0 // indirect
 	golang.org/x/term v0.5.0 // indirect
diff --git a/go.sum b/go.sum
index 64acfd6..8e2002d 100644
--- a/go.sum
+++ b/go.sum
@@ -59,6 +59,7 @@
 github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
 github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
 github.com/Microsoft/hcsshim v0.9.6 h1:VwnDOgLeoi2du6dAznfmspNqTiwczvjv4K7NxuY9jsY=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -81,10 +82,12 @@
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
 github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
+github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
 github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=
 github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
 github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -98,6 +101,7 @@
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
@@ -143,6 +147,7 @@
 github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
@@ -156,6 +161,7 @@
 github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
 github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
+github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
@@ -187,8 +193,8 @@
 github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
 github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
-github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
+github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
@@ -245,8 +251,8 @@
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
 github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
-github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
-github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
+github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
+github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -283,8 +289,8 @@
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
-github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -325,8 +331,8 @@
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
-github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
+github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
 github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -379,8 +385,9 @@
 github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
 github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
 github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
 github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
@@ -446,7 +453,9 @@
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
 github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
 github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
@@ -471,6 +480,8 @@
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg=
 github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
+github.com/pravega/zookeeper-operator v0.2.15 h1:u7m8S3DFKDcLLk6aSBUFxhJb22HL0IAYE8qxycd4Bdo=
+github.com/pravega/zookeeper-operator v0.2.15/go.mod h1:Ijkj9cqQjl4O0OAVLY0mVKvs3nAEnmp4vVTdbk7k0Ak=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
@@ -524,6 +535,7 @@
 github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
@@ -586,12 +598,14 @@
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
 go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
-go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
+go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
-go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
 go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
+go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
 go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
 go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
 go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
@@ -706,8 +720,9 @@
 golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg=
 golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw=
+golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -933,7 +948,6 @@
 google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@@ -944,6 +958,7 @@
 google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I=
 google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -966,6 +981,7 @@
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
 google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
 google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
@@ -996,6 +1012,7 @@
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1008,6 +1025,7 @@
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
diff --git a/hack/headers/zookeeper-operator-header.yaml.txt b/hack/headers/zookeeper-operator-header.yaml.txt
index cb39d05..ba92964 100644
--- a/hack/headers/zookeeper-operator-header.yaml.txt
+++ b/hack/headers/zookeeper-operator-header.yaml.txt
@@ -6,4 +6,3 @@
 #
 # http://www.apache.org/licenses/LICENSE-2.0
 #
-# Find source at: https://github.com/pravega/zookeeper-operator/tree/v0.2.14
\ No newline at end of file
diff --git a/hack/zk-operator/update-crd.sh b/hack/zk-operator/update-crd.sh
index 6bf018b..ed1d2ec 100755
--- a/hack/zk-operator/update-crd.sh
+++ b/hack/zk-operator/update-crd.sh
@@ -26,6 +26,7 @@
 # Fetch the correct dependency Zookeeper CRD, package with other CRDS
 {
   cat hack/headers/zookeeper-operator-header.yaml.txt;
+  printf "# Find source at: https://github.com/pravega/zookeeper-operator/tree/${ZK_OP_VERSION}"
   printf "\n\n---\n"
   curl -sL "https://raw.githubusercontent.com/pravega/zookeeper-operator/${ZK_OP_VERSION}/config/crd/bases/zookeeper.pravega.io_zookeeperclusters.yaml" \
     | sed -e "/^  annotations:$/a \\
diff --git a/helm/solr-operator/Chart.yaml b/helm/solr-operator/Chart.yaml
index d7691bc..4ae88f2 100644
--- a/helm/solr-operator/Chart.yaml
+++ b/helm/solr-operator/Chart.yaml
@@ -35,7 +35,7 @@
 icon: https://solr.apache.org/theme/images/identity/Solr_Logo_on_white.png
 dependencies:
   - name: 'zookeeper-operator'
-    version: 0.2.14
+    version: 0.2.15
     repository: https://charts.pravega.io
     condition: zookeeper-operator.install
 annotations:
@@ -59,6 +59,15 @@
       links:
         - name: GitHub PR
           url: https://github.com/apache/solr-operator/pull/473
+    - kind: changed
+      description: The required Zookeeper Operator version has been upgraded to v0.2.15
+      links:
+        - name: GitHub Issue
+          url: https://github.com/apache/solr-operator/issues/549
+        - name: GitHub PR
+          url: https://github.com/apache/solr-operator/pull/550
+        - name: Zookeeper Operator v0.2.15 Release
+          url: https://github.com/pravega/zookeeper-operator/releases/tag/v0.2.15
     - kind: fixed
       description: Fix bug with named PVCs
       links:
diff --git a/helm/solr-operator/README.md b/helm/solr-operator/README.md
index df91ed4..9b68501 100644
--- a/helm/solr-operator/README.md
+++ b/helm/solr-operator/README.md
@@ -19,7 +19,7 @@
 Before installing the Solr Operator, we need to install the [Zookeeper Operator](https://github.com/pravega/zookeeper-operator).
 This is because the Solr Operator, in most instances, relies on the Zookeeper Operator to create the Zookeeper clusters that Solr coordinates through.
 
-The Solr Operator helm chart has a conditional dependency on the [official Zookeeper Operator helm chart](https://github.com/pravega/zookeeper-operator/tree/v0.2.14/charts/zookeeper-operator#installing-the-chart),
+The Solr Operator helm chart has a conditional dependency on the [official Zookeeper Operator helm chart](https://github.com/pravega/zookeeper-operator/tree/v0.2.15/charts/zookeeper-operator#installing-the-chart),
 which is enabled **by default**.
 
 If you wish to manage the installation of the Zookeeper Operator yourself, set:
@@ -192,7 +192,7 @@
 
 ### Configuring the Zookeeper Operator
 
-If you have `zookeeper-operator.install` set to `true`, which is the default behavior, then you can use the [Zookeeper Operator Chart values](https://github.com/pravega/zookeeper-operator/tree/v0.2.14/charts/zookeeper-operator#configuration).
+If you have `zookeeper-operator.install` set to `true`, which is the default behavior, then you can use the [Zookeeper Operator Chart values](https://github.com/pravega/zookeeper-operator/tree/v0.2.15/charts/zookeeper-operator#configuration).
 You must prefix every Zookeeper Operator configuration with `zookeeper-operator.`, in order for it to be used.
 
 For example:
diff --git a/main.go b/main.go
index 574a764..ded576f 100644
--- a/main.go
+++ b/main.go
@@ -23,9 +23,9 @@
 	"flag"
 	"fmt"
 	"github.com/apache/solr-operator/controllers/util/solr_api"
-	"github.com/apache/solr-operator/controllers/zk_api"
 	"github.com/apache/solr-operator/version"
 	"github.com/fsnotify/fsnotify"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	"io/ioutil"
 	"net/http"
 	"os"
@@ -85,7 +85,7 @@
 
 	utilruntime.Must(solrv1beta1.AddToScheme(scheme))
 
-	utilruntime.Must(zk_api.AddToScheme(scheme))
+	utilruntime.Must(zkApi.AddToScheme(scheme))
 	//+kubebuilder:scaffold:scheme
 
 	flag.BoolVar(&useZookeeperCRD, "zk-operator", true, "The operator will not use the zk operator & crd when this flag is set to false.")
diff --git a/tests/e2e/resource_utils_test.go b/tests/e2e/resource_utils_test.go
index bb32f59..87d3ada 100644
--- a/tests/e2e/resource_utils_test.go
+++ b/tests/e2e/resource_utils_test.go
@@ -20,13 +20,13 @@
 import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	policyv1 "k8s.io/api/policy/v1"
 	"regexp"
 	"time"
 
 	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
 	"github.com/apache/solr-operator/controllers/util"
-	zk_api "github.com/apache/solr-operator/controllers/zk_api"
 	"golang.org/x/net/context"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -722,7 +722,7 @@
 	cleanupObjects := []client.Object{
 		// Solr Operator CRDs, modify this list whenever CRDs are added/deleted
 		&solrv1beta1.SolrCloud{}, &solrv1beta1.SolrBackup{}, &solrv1beta1.SolrPrometheusExporter{},
-		&zk_api.ZookeeperCluster{},
+		&zkApi.ZookeeperCluster{},
 
 		// All dependent Kubernetes types, in order of dependence (deployment then replicaSet then pod)
 		&corev1.ConfigMap{}, &netv1.Ingress{},
diff --git a/tests/e2e/suite_test.go b/tests/e2e/suite_test.go
index d9e87c3..d16c9e0 100644
--- a/tests/e2e/suite_test.go
+++ b/tests/e2e/suite_test.go
@@ -21,10 +21,10 @@
 	"context"
 	"fmt"
 	solrv1beta1 "github.com/apache/solr-operator/api/v1beta1"
-	"github.com/apache/solr-operator/controllers/zk_api"
 	"github.com/apache/solr-operator/version"
 	"github.com/go-logr/logr"
 	"github.com/onsi/ginkgo/v2/types"
+	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
 	"helm.sh/helm/v3/pkg/release"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -104,7 +104,7 @@
 
 	By("setting up the k8s clients")
 	Expect(solrv1beta1.AddToScheme(scheme.Scheme)).To(Succeed())
-	Expect(zk_api.AddToScheme(scheme.Scheme)).To(Succeed())
+	Expect(zkApi.AddToScheme(scheme.Scheme)).To(Succeed())
 
 	k8sClient, err = client.New(k8sConfig, client.Options{Scheme: scheme.Scheme})
 	Expect(err).NotTo(HaveOccurred(), "Could not create controllerRuntime Kubernetes client")
diff --git a/tests/scripts/manage_e2e_tests.sh b/tests/scripts/manage_e2e_tests.sh
index 3ba0f28..f85a3e1 100755
--- a/tests/scripts/manage_e2e_tests.sh
+++ b/tests/scripts/manage_e2e_tests.sh
@@ -40,7 +40,7 @@
 EOF
 }
 
-ADDITIONAL_IMAGES=("pravega/zookeeper:0.2.14")
+ADDITIONAL_IMAGES=("pravega/zookeeper:0.2.15")
 OPTIND=1
 while getopts hv:i:k:s:a: opt; do
     case $opt in
diff --git a/versions.props b/versions.props
index 559dfca..ac79364 100644
--- a/versions.props
+++ b/versions.props
@@ -1 +1 @@
-zookeeper-operator = v0.2.14
+zookeeper-operator = v0.2.15